Skip to content

Commit

Permalink
ipv4: Create and use route lookup helpers.
Browse files Browse the repository at this point in the history
The idea here is this minimizes the number of places one has to edit
in order to make changes to how flows are defined and used.

Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
davem330 committed Mar 12, 2011
1 parent 1561747 commit 78fbfd8
Show file tree
Hide file tree
Showing 23 changed files with 206 additions and 326 deletions.
8 changes: 1 addition & 7 deletions drivers/infiniband/core/addr.c
Original file line number Diff line number Diff line change
Expand Up @@ -183,17 +183,11 @@ static int addr4_resolve(struct sockaddr_in *src_in,
{
__be32 src_ip = src_in->sin_addr.s_addr;
__be32 dst_ip = dst_in->sin_addr.s_addr;
struct flowi fl;
struct rtable *rt;
struct neighbour *neigh;
int ret;

memset(&fl, 0, sizeof fl);
fl.nl_u.ip4_u.daddr = dst_ip;
fl.nl_u.ip4_u.saddr = src_ip;
fl.oif = addr->bound_dev_if;

rt = ip_route_output_key(&init_net, &fl);
rt = ip_route_output(&init_net, dst_ip, src_ip, 0, addr->bound_dev_if);
if (IS_ERR(rt)) {
ret = PTR_ERR(rt);
goto out;
Expand Down
21 changes: 4 additions & 17 deletions drivers/infiniband/hw/cxgb3/iwch_cm.c
Original file line number Diff line number Diff line change
Expand Up @@ -338,23 +338,10 @@ static struct rtable *find_route(struct t3cdev *dev, __be32 local_ip,
__be16 peer_port, u8 tos)
{
struct rtable *rt;
struct flowi fl = {
.oif = 0,
.nl_u = {
.ip4_u = {
.daddr = peer_ip,
.saddr = local_ip,
.tos = tos}
},
.proto = IPPROTO_TCP,
.uli_u = {
.ports = {
.sport = local_port,
.dport = peer_port}
}
};

rt = ip_route_output_flow(&init_net, &fl, NULL);

rt = ip_route_output_ports(&init_net, NULL, peer_ip, local_ip,
peer_port, local_port, IPPROTO_TCP,
tos, 0);
if (IS_ERR(rt))
return NULL;
return rt;
Expand Down
21 changes: 4 additions & 17 deletions drivers/infiniband/hw/cxgb4/cm.c
Original file line number Diff line number Diff line change
Expand Up @@ -315,23 +315,10 @@ static struct rtable *find_route(struct c4iw_dev *dev, __be32 local_ip,
__be16 peer_port, u8 tos)
{
struct rtable *rt;
struct flowi fl = {
.oif = 0,
.nl_u = {
.ip4_u = {
.daddr = peer_ip,
.saddr = local_ip,
.tos = tos}
},
.proto = IPPROTO_TCP,
.uli_u = {
.ports = {
.sport = local_port,
.dport = peer_port}
}
};

rt = ip_route_output_flow(&init_net, &fl, NULL);

rt = ip_route_output_ports(&init_net, NULL, peer_ip, local_ip,
peer_port, local_port, IPPROTO_TCP,
tos, 0);
if (IS_ERR(rt))
return NULL;
return rt;
Expand Down
5 changes: 1 addition & 4 deletions drivers/infiniband/hw/nes/nes_cm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1104,15 +1104,12 @@ static inline int mini_cm_accelerated(struct nes_cm_core *cm_core,
static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip, int arpindex)
{
struct rtable *rt;
struct flowi fl;
struct neighbour *neigh;
int rc = arpindex;
struct net_device *netdev;
struct nes_adapter *nesadapter = nesvnic->nesdev->nesadapter;

memset(&fl, 0, sizeof fl);
fl.nl_u.ip4_u.daddr = htonl(dst_ip);
rt = ip_route_output_key(&init_net, &fl);
rt = ip_route_output(&init_net, htonl(dst_ip), 0, 0, 0);
if (IS_ERR(rt)) {
printk(KERN_ERR "%s: ip_route_output_key failed for 0x%08X\n",
__func__, dst_ip);
Expand Down
12 changes: 4 additions & 8 deletions drivers/net/bonding/bond_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2676,7 +2676,6 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
__be32 *targets = bond->params.arp_targets;
struct vlan_entry *vlan;
struct net_device *vlan_dev;
struct flowi fl;
struct rtable *rt;

for (i = 0; (i < BOND_MAX_ARP_TARGETS); i++) {
Expand All @@ -2695,15 +2694,12 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
* determine which VLAN interface would be used, so we
* can tag the ARP with the proper VLAN tag.
*/
memset(&fl, 0, sizeof(fl));
fl.fl4_dst = targets[i];
fl.fl4_tos = RTO_ONLINK;

rt = ip_route_output_key(dev_net(bond->dev), &fl);
rt = ip_route_output(dev_net(bond->dev), targets[i], 0,
RTO_ONLINK, 0);
if (IS_ERR(rt)) {
if (net_ratelimit()) {
pr_warning("%s: no route to arp_ip_target %pI4\n",
bond->dev->name, &fl.fl4_dst);
bond->dev->name, &targets[i]);
}
continue;
}
Expand Down Expand Up @@ -2739,7 +2735,7 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)

if (net_ratelimit()) {
pr_warning("%s: no path to arp_ip_target %pI4 via rt.dev %s\n",
bond->dev->name, &fl.fl4_dst,
bond->dev->name, &targets[i],
rt->dst.dev ? rt->dst.dev->name : "NULL");
}
ip_rt_put(rt);
Expand Down
16 changes: 5 additions & 11 deletions drivers/net/cnic.c
Original file line number Diff line number Diff line change
Expand Up @@ -3407,20 +3407,14 @@ static int cnic_get_v4_route(struct sockaddr_in *dst_addr,
struct dst_entry **dst)
{
#if defined(CONFIG_INET)
struct flowi fl;
int err;
struct rtable *rt;

memset(&fl, 0, sizeof(fl));
fl.nl_u.ip4_u.daddr = dst_addr->sin_addr.s_addr;

rt = ip_route_output_key(&init_net, &fl);
err = 0;
if (!IS_ERR(rt))
rt = ip_route_output(&init_net, dst_addr->sin_addr.s_addr, 0, 0, 0);
if (!IS_ERR(rt)) {
*dst = &rt->dst;
else
err = PTR_ERR(rt);
return err;
return 0;
}
return PTR_ERR(rt);
#else
return -ENETUNREACH;
#endif
Expand Down
45 changes: 18 additions & 27 deletions drivers/net/pptp.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,18 +189,14 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
if (sk_pppox(po)->sk_state & PPPOX_DEAD)
goto tx_error;

{
struct flowi fl = { .oif = 0,
.nl_u = {
.ip4_u = {
.daddr = opt->dst_addr.sin_addr.s_addr,
.saddr = opt->src_addr.sin_addr.s_addr,
.tos = RT_TOS(0) } },
.proto = IPPROTO_GRE };
rt = ip_route_output_key(&init_net, &fl);
if (IS_ERR(rt))
goto tx_error;
}
rt = ip_route_output_ports(&init_net, NULL,
opt->dst_addr.sin_addr.s_addr,
opt->src_addr.sin_addr.s_addr,
0, 0, IPPROTO_GRE,
RT_TOS(0), 0);
if (IS_ERR(rt))
goto tx_error;

tdev = rt->dst.dev;

max_headroom = LL_RESERVED_SPACE(tdev) + sizeof(*iph) + sizeof(*hdr) + 2;
Expand Down Expand Up @@ -467,22 +463,17 @@ static int pptp_connect(struct socket *sock, struct sockaddr *uservaddr,
po->chan.private = sk;
po->chan.ops = &pptp_chan_ops;

{
struct flowi fl = {
.nl_u = {
.ip4_u = {
.daddr = opt->dst_addr.sin_addr.s_addr,
.saddr = opt->src_addr.sin_addr.s_addr,
.tos = RT_CONN_FLAGS(sk) } },
.proto = IPPROTO_GRE };
security_sk_classify_flow(sk, &fl);
rt = ip_route_output_key(&init_net, &fl);
if (IS_ERR(rt)) {
error = -EHOSTUNREACH;
goto end;
}
sk_setup_caps(sk, &rt->dst);
rt = ip_route_output_ports(&init_net, sk,
opt->dst_addr.sin_addr.s_addr,
opt->src_addr.sin_addr.s_addr,
0, 0,
IPPROTO_GRE, RT_CONN_FLAGS(sk), 0);
if (IS_ERR(rt)) {
error = -EHOSTUNREACH;
goto end;
}
sk_setup_caps(sk, &rt->dst);

po->chan.mtu = dst_mtu(&rt->dst);
if (!po->chan.mtu)
po->chan.mtu = PPP_MTU;
Expand Down
20 changes: 3 additions & 17 deletions drivers/scsi/cxgbi/libcxgbi.c
Original file line number Diff line number Diff line change
Expand Up @@ -451,26 +451,12 @@ static struct cxgbi_sock *cxgbi_sock_create(struct cxgbi_device *cdev)
}

static struct rtable *find_route_ipv4(__be32 saddr, __be32 daddr,
__be16 sport, __be16 dport, u8 tos)
__be16 sport, __be16 dport, u8 tos)
{
struct rtable *rt;
struct flowi fl = {
.oif = 0,
.nl_u = {
.ip4_u = {
.daddr = daddr,
.saddr = saddr,
.tos = tos }
},
.proto = IPPROTO_TCP,
.uli_u = {
.ports = {
.sport = sport,
.dport = dport }
}
};

rt = ip_route_output_flow(&init_net, &fl, NULL);
rt = ip_route_output_ports(&init_net, NULL, daddr, saddr,
dport, sport, IPPROTO_TCP, tos, 0);
if (IS_ERR(rt))
return NULL;

Expand Down
48 changes: 48 additions & 0 deletions include/net/route.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,54 @@ static inline struct rtable *ip_route_output_key(struct net *net, struct flowi *
return ip_route_output_flow(net, flp, NULL);
}

static inline struct rtable *ip_route_output(struct net *net, __be32 daddr,
__be32 saddr, u8 tos, int oif)
{
struct flowi fl = {
.oif = oif,
.fl4_dst = daddr,
.fl4_src = saddr,
.fl4_tos = tos,
};
return ip_route_output_key(net, &fl);
}

static inline struct rtable *ip_route_output_ports(struct net *net, struct sock *sk,
__be32 daddr, __be32 saddr,
__be16 dport, __be16 sport,
__u8 proto, __u8 tos, int oif)
{
struct flowi fl = {
.oif = oif,
.flags = sk ? inet_sk_flowi_flags(sk) : 0,
.mark = sk ? sk->sk_mark : 0,
.fl4_dst = daddr,
.fl4_src = saddr,
.fl4_tos = tos,
.proto = proto,
.fl_ip_dport = dport,
.fl_ip_sport = sport,
};
if (sk)
security_sk_classify_flow(sk, &fl);
return ip_route_output_flow(net, &fl, sk);
}

static inline struct rtable *ip_route_output_gre(struct net *net,
__be32 daddr, __be32 saddr,
__be32 gre_key, __u8 tos, int oif)
{
struct flowi fl = {
.oif = oif,
.fl4_dst = daddr,
.fl4_src = saddr,
.fl4_tos = tos,
.proto = IPPROTO_GRE,
.fl_gre_key = gre_key,
};
return ip_route_output_key(net, &fl);
}

extern int ip_route_input_common(struct sk_buff *skb, __be32 dst, __be32 src,
u8 tos, struct net_device *devin, bool noref);

Expand Down
4 changes: 1 addition & 3 deletions net/atm/clip.c
Original file line number Diff line number Diff line change
Expand Up @@ -502,8 +502,6 @@ static int clip_setentry(struct atm_vcc *vcc, __be32 ip)
struct atmarp_entry *entry;
int error;
struct clip_vcc *clip_vcc;
struct flowi fl = { .fl4_dst = ip,
.fl4_tos = 1 };
struct rtable *rt;

if (vcc->push != clip_push) {
Expand All @@ -520,7 +518,7 @@ static int clip_setentry(struct atm_vcc *vcc, __be32 ip)
unlink_clip_vcc(clip_vcc);
return 0;
}
rt = ip_route_output_key(&init_net, &fl);
rt = ip_route_output(&init_net, ip, 0, 1, 0);
if (IS_ERR(rt))
return PTR_ERR(rt);
neigh = __neigh_lookup(&clip_tbl, &ip, rt->dst.dev, 1);
Expand Down
7 changes: 2 additions & 5 deletions net/bridge/br_netfilter.c
Original file line number Diff line number Diff line change
Expand Up @@ -412,10 +412,6 @@ static int br_nf_pre_routing_finish(struct sk_buff *skb)
nf_bridge->mask ^= BRNF_NF_BRIDGE_PREROUTING;
if (dnat_took_place(skb)) {
if ((err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev))) {
struct flowi fl = {
.fl4_dst = iph->daddr,
.fl4_tos = RT_TOS(iph->tos),
};
struct in_device *in_dev = __in_dev_get_rcu(dev);

/* If err equals -EHOSTUNREACH the error is due to a
Expand All @@ -428,7 +424,8 @@ static int br_nf_pre_routing_finish(struct sk_buff *skb)
if (err != -EHOSTUNREACH || !in_dev || IN_DEV_FORWARD(in_dev))
goto free_skb;

rt = ip_route_output_key(dev_net(dev), &fl);
rt = ip_route_output(dev_net(dev), iph->daddr, 0,
RT_TOS(iph->tos), 0);
if (!IS_ERR(rt)) {
/* - Bridged-and-DNAT'ed traffic doesn't
* require ip_forwarding. */
Expand Down
20 changes: 4 additions & 16 deletions net/ipv4/af_inet.c
Original file line number Diff line number Diff line change
Expand Up @@ -1157,22 +1157,10 @@ int inet_sk_rebuild_header(struct sock *sk)
daddr = inet->inet_daddr;
if (inet->opt && inet->opt->srr)
daddr = inet->opt->faddr;
{
struct flowi fl = {
.oif = sk->sk_bound_dev_if,
.mark = sk->sk_mark,
.fl4_dst = daddr,
.fl4_src = inet->inet_saddr,
.fl4_tos = RT_CONN_FLAGS(sk),
.proto = sk->sk_protocol,
.flags = inet_sk_flowi_flags(sk),
.fl_ip_sport = inet->inet_sport,
.fl_ip_dport = inet->inet_dport,
};

security_sk_classify_flow(sk, &fl);
rt = ip_route_output_flow(sock_net(sk), &fl, sk);
}
rt = ip_route_output_ports(sock_net(sk), sk, daddr, inet->inet_saddr,
inet->inet_dport, inet->inet_sport,
sk->sk_protocol, RT_CONN_FLAGS(sk),
sk->sk_bound_dev_if);
if (!IS_ERR(rt)) {
err = 0;
sk_setup_caps(sk, &rt->dst);
Expand Down
Loading

0 comments on commit 78fbfd8

Please sign in to comment.