X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=net%2Fipv4%2Fxfrm4_policy.c;h=c63de0a72aba746184e1c4e9f97aefe57cdff1a8;hb=5c52ba170f8167511bdb65b981f4582100c40675;hp=b4948c170b3ea37ac4c41a17901bdd4ff9ba2f35;hpb=862b82c6f960cc61274d370aa78ce1112f92a83e;p=linux-2.6 diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index b4948c170b..c63de0a72a 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c @@ -36,7 +36,7 @@ static struct dst_entry *xfrm4_dst_lookup(int tos, xfrm_address_t *saddr, if (saddr) fl.fl4_src = saddr->a4; - err = __ip_route_output_key(&rt, &fl); + err = __ip_route_output_key(&init_net, &rt, &fl); dst = &rt->u.dst; if (err) dst = ERR_PTR(err); @@ -84,6 +84,12 @@ static int xfrm4_get_tos(struct flowi *fl) return fl->fl4_tos; } +static int xfrm4_init_path(struct xfrm_dst *path, struct dst_entry *dst, + int nfheader_len) +{ + return 0; +} + static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev) { struct rtable *rt = (struct rtable *)xdst->route; @@ -115,7 +121,7 @@ static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev) } static void -_decode_session4(struct sk_buff *skb, struct flowi *fl) +_decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse) { struct iphdr *iph = ip_hdr(skb); u8 *xprth = skb_network_header(skb) + iph->ihl * 4; @@ -131,8 +137,8 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl) if (pskb_may_pull(skb, xprth + 4 - skb->data)) { __be16 *ports = (__be16 *)xprth; - fl->fl_ip_sport = ports[0]; - fl->fl_ip_dport = ports[1]; + fl->fl_ip_sport = ports[!!reverse]; + fl->fl_ip_dport = ports[!reverse]; } break; @@ -174,12 +180,12 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl) } } fl->proto = iph->protocol; - fl->fl4_dst = iph->daddr; - fl->fl4_src = iph->saddr; + fl->fl4_dst = reverse ? iph->saddr : iph->daddr; + fl->fl4_src = reverse ? iph->daddr : iph->saddr; fl->fl4_tos = iph->tos; } -static inline int xfrm4_garbage_collect(void) +static inline int xfrm4_garbage_collect(struct dst_ops *ops) { xfrm4_policy_afinfo.garbage_collect(); return (atomic_read(&xfrm4_dst_ops.entries) > xfrm4_dst_ops.gc_thresh*2); @@ -214,7 +220,8 @@ static void xfrm4_dst_ifdown(struct dst_entry *dst, struct net_device *dev, xdst = (struct xfrm_dst *)dst; if (xdst->u.rt.idev->dev == dev) { - struct in_device *loopback_idev = in_dev_get(init_net.loopback_dev); + struct in_device *loopback_idev = + in_dev_get(dev_net(dev)->loopback_dev); BUG_ON(!loopback_idev); do { @@ -240,6 +247,7 @@ static struct dst_ops xfrm4_dst_ops = { .local_out = __ip_local_out, .gc_thresh = 1024, .entry_size = sizeof(struct xfrm_dst), + .entries = ATOMIC_INIT(0), }; static struct xfrm_policy_afinfo xfrm4_policy_afinfo = { @@ -250,6 +258,7 @@ static struct xfrm_policy_afinfo xfrm4_policy_afinfo = { .find_bundle = __xfrm4_find_bundle, .decode_session = _decode_session4, .get_tos = xfrm4_get_tos, + .init_path = xfrm4_init_path, .fill_dst = xfrm4_fill_dst, };