diff options
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/ah4.c | 2 | ||||
-rw-r--r-- | net/ipv4/esp4.c | 2 | ||||
-rw-r--r-- | net/ipv4/fib_frontend.c | 55 | ||||
-rw-r--r-- | net/ipv4/ipcomp.c | 11 | ||||
-rw-r--r-- | net/ipv4/xfrm4_output.c | 8 | ||||
-rw-r--r-- | net/ipv4/xfrm4_state.c | 9 | ||||
-rw-r--r-- | net/ipv4/xfrm4_tunnel.c | 2 |
7 files changed, 76 insertions, 13 deletions
diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c index 0e98f2235b6e..514c85b2631a 100644 --- a/net/ipv4/ah4.c +++ b/net/ipv4/ah4.c | |||
@@ -200,7 +200,7 @@ static void ah4_err(struct sk_buff *skb, u32 info) | |||
200 | xfrm_state_put(x); | 200 | xfrm_state_put(x); |
201 | } | 201 | } |
202 | 202 | ||
203 | static int ah_init_state(struct xfrm_state *x, void *args) | 203 | static int ah_init_state(struct xfrm_state *x) |
204 | { | 204 | { |
205 | struct ah_data *ahp = NULL; | 205 | struct ah_data *ahp = NULL; |
206 | struct xfrm_algo_desc *aalg_desc; | 206 | struct xfrm_algo_desc *aalg_desc; |
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c index eae84cc39d3f..ba57446d5d1f 100644 --- a/net/ipv4/esp4.c +++ b/net/ipv4/esp4.c | |||
@@ -362,7 +362,7 @@ static void esp_destroy(struct xfrm_state *x) | |||
362 | kfree(esp); | 362 | kfree(esp); |
363 | } | 363 | } |
364 | 364 | ||
365 | static int esp_init_state(struct xfrm_state *x, void *args) | 365 | static int esp_init_state(struct xfrm_state *x) |
366 | { | 366 | { |
367 | struct esp_data *esp = NULL; | 367 | struct esp_data *esp = NULL; |
368 | 368 | ||
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 563e7d612706..cd8e45ab9580 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c | |||
@@ -516,6 +516,60 @@ static void fib_del_ifaddr(struct in_ifaddr *ifa) | |||
516 | #undef BRD1_OK | 516 | #undef BRD1_OK |
517 | } | 517 | } |
518 | 518 | ||
519 | static void nl_fib_lookup(struct fib_result_nl *frn, struct fib_table *tb ) | ||
520 | { | ||
521 | |||
522 | struct fib_result res; | ||
523 | struct flowi fl = { .nl_u = { .ip4_u = { .daddr = frn->fl_addr, | ||
524 | .fwmark = frn->fl_fwmark, | ||
525 | .tos = frn->fl_tos, | ||
526 | .scope = frn->fl_scope } } }; | ||
527 | if (tb) { | ||
528 | local_bh_disable(); | ||
529 | |||
530 | frn->tb_id = tb->tb_id; | ||
531 | frn->err = tb->tb_lookup(tb, &fl, &res); | ||
532 | |||
533 | if (!frn->err) { | ||
534 | frn->prefixlen = res.prefixlen; | ||
535 | frn->nh_sel = res.nh_sel; | ||
536 | frn->type = res.type; | ||
537 | frn->scope = res.scope; | ||
538 | } | ||
539 | local_bh_enable(); | ||
540 | } | ||
541 | } | ||
542 | |||
543 | static void nl_fib_input(struct sock *sk, int len) | ||
544 | { | ||
545 | struct sk_buff *skb = NULL; | ||
546 | struct nlmsghdr *nlh = NULL; | ||
547 | struct fib_result_nl *frn; | ||
548 | int err; | ||
549 | u32 pid; | ||
550 | struct fib_table *tb; | ||
551 | |||
552 | skb = skb_recv_datagram(sk, 0, 0, &err); | ||
553 | nlh = (struct nlmsghdr *)skb->data; | ||
554 | |||
555 | frn = (struct fib_result_nl *) NLMSG_DATA(nlh); | ||
556 | tb = fib_get_table(frn->tb_id_in); | ||
557 | |||
558 | nl_fib_lookup(frn, tb); | ||
559 | |||
560 | pid = nlh->nlmsg_pid; /*pid of sending process */ | ||
561 | NETLINK_CB(skb).groups = 0; /* not in mcast group */ | ||
562 | NETLINK_CB(skb).pid = 0; /* from kernel */ | ||
563 | NETLINK_CB(skb).dst_pid = pid; | ||
564 | NETLINK_CB(skb).dst_groups = 0; /* unicast */ | ||
565 | netlink_unicast(sk, skb, pid, MSG_DONTWAIT); | ||
566 | } | ||
567 | |||
568 | static void nl_fib_lookup_init(void) | ||
569 | { | ||
570 | netlink_kernel_create(NETLINK_FIB_LOOKUP, nl_fib_input); | ||
571 | } | ||
572 | |||
519 | static void fib_disable_ip(struct net_device *dev, int force) | 573 | static void fib_disable_ip(struct net_device *dev, int force) |
520 | { | 574 | { |
521 | if (fib_sync_down(0, dev, force)) | 575 | if (fib_sync_down(0, dev, force)) |
@@ -604,6 +658,7 @@ void __init ip_fib_init(void) | |||
604 | 658 | ||
605 | register_netdevice_notifier(&fib_netdev_notifier); | 659 | register_netdevice_notifier(&fib_netdev_notifier); |
606 | register_inetaddr_notifier(&fib_inetaddr_notifier); | 660 | register_inetaddr_notifier(&fib_inetaddr_notifier); |
661 | nl_fib_lookup_init(); | ||
607 | } | 662 | } |
608 | 663 | ||
609 | EXPORT_SYMBOL(inet_addr_type); | 664 | EXPORT_SYMBOL(inet_addr_type); |
diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c index 1a23c5263b99..2065944fd9e5 100644 --- a/net/ipv4/ipcomp.c +++ b/net/ipv4/ipcomp.c | |||
@@ -236,15 +236,10 @@ static struct xfrm_state *ipcomp_tunnel_create(struct xfrm_state *x) | |||
236 | t->props.mode = 1; | 236 | t->props.mode = 1; |
237 | t->props.saddr.a4 = x->props.saddr.a4; | 237 | t->props.saddr.a4 = x->props.saddr.a4; |
238 | t->props.flags = x->props.flags; | 238 | t->props.flags = x->props.flags; |
239 | 239 | ||
240 | t->type = xfrm_get_type(IPPROTO_IPIP, t->props.family); | 240 | if (xfrm_init_state(t)) |
241 | if (t->type == NULL) | ||
242 | goto error; | ||
243 | |||
244 | if (t->type->init_state(t, NULL)) | ||
245 | goto error; | 241 | goto error; |
246 | 242 | ||
247 | t->km.state = XFRM_STATE_VALID; | ||
248 | atomic_set(&t->tunnel_users, 1); | 243 | atomic_set(&t->tunnel_users, 1); |
249 | out: | 244 | out: |
250 | return t; | 245 | return t; |
@@ -422,7 +417,7 @@ static void ipcomp_destroy(struct xfrm_state *x) | |||
422 | kfree(ipcd); | 417 | kfree(ipcd); |
423 | } | 418 | } |
424 | 419 | ||
425 | static int ipcomp_init_state(struct xfrm_state *x, void *args) | 420 | static int ipcomp_init_state(struct xfrm_state *x) |
426 | { | 421 | { |
427 | int err; | 422 | int err; |
428 | struct ipcomp_data *ipcd; | 423 | struct ipcomp_data *ipcd; |
diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c index af2392ae5769..66620a95942a 100644 --- a/net/ipv4/xfrm4_output.c +++ b/net/ipv4/xfrm4_output.c | |||
@@ -33,6 +33,7 @@ static void xfrm4_encap(struct sk_buff *skb) | |||
33 | struct dst_entry *dst = skb->dst; | 33 | struct dst_entry *dst = skb->dst; |
34 | struct xfrm_state *x = dst->xfrm; | 34 | struct xfrm_state *x = dst->xfrm; |
35 | struct iphdr *iph, *top_iph; | 35 | struct iphdr *iph, *top_iph; |
36 | int flags; | ||
36 | 37 | ||
37 | iph = skb->nh.iph; | 38 | iph = skb->nh.iph; |
38 | skb->h.ipiph = iph; | 39 | skb->h.ipiph = iph; |
@@ -51,10 +52,13 @@ static void xfrm4_encap(struct sk_buff *skb) | |||
51 | 52 | ||
52 | /* DS disclosed */ | 53 | /* DS disclosed */ |
53 | top_iph->tos = INET_ECN_encapsulate(iph->tos, iph->tos); | 54 | top_iph->tos = INET_ECN_encapsulate(iph->tos, iph->tos); |
54 | if (x->props.flags & XFRM_STATE_NOECN) | 55 | |
56 | flags = x->props.flags; | ||
57 | if (flags & XFRM_STATE_NOECN) | ||
55 | IP_ECN_clear(top_iph); | 58 | IP_ECN_clear(top_iph); |
56 | 59 | ||
57 | top_iph->frag_off = iph->frag_off & htons(IP_DF); | 60 | top_iph->frag_off = (flags & XFRM_STATE_NOPMTUDISC) ? |
61 | 0 : (iph->frag_off & htons(IP_DF)); | ||
58 | if (!top_iph->frag_off) | 62 | if (!top_iph->frag_off) |
59 | __ip_select_ident(top_iph, dst, 0); | 63 | __ip_select_ident(top_iph, dst, 0); |
60 | 64 | ||
diff --git a/net/ipv4/xfrm4_state.c b/net/ipv4/xfrm4_state.c index 223a2e83853f..050611d7a967 100644 --- a/net/ipv4/xfrm4_state.c +++ b/net/ipv4/xfrm4_state.c | |||
@@ -7,12 +7,20 @@ | |||
7 | * | 7 | * |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <net/ip.h> | ||
10 | #include <net/xfrm.h> | 11 | #include <net/xfrm.h> |
11 | #include <linux/pfkeyv2.h> | 12 | #include <linux/pfkeyv2.h> |
12 | #include <linux/ipsec.h> | 13 | #include <linux/ipsec.h> |
13 | 14 | ||
14 | static struct xfrm_state_afinfo xfrm4_state_afinfo; | 15 | static struct xfrm_state_afinfo xfrm4_state_afinfo; |
15 | 16 | ||
17 | static int xfrm4_init_flags(struct xfrm_state *x) | ||
18 | { | ||
19 | if (ipv4_config.no_pmtu_disc) | ||
20 | x->props.flags |= XFRM_STATE_NOPMTUDISC; | ||
21 | return 0; | ||
22 | } | ||
23 | |||
16 | static void | 24 | static void |
17 | __xfrm4_init_tempsel(struct xfrm_state *x, struct flowi *fl, | 25 | __xfrm4_init_tempsel(struct xfrm_state *x, struct flowi *fl, |
18 | struct xfrm_tmpl *tmpl, | 26 | struct xfrm_tmpl *tmpl, |
@@ -109,6 +117,7 @@ __xfrm4_find_acq(u8 mode, u32 reqid, u8 proto, | |||
109 | static struct xfrm_state_afinfo xfrm4_state_afinfo = { | 117 | static struct xfrm_state_afinfo xfrm4_state_afinfo = { |
110 | .family = AF_INET, | 118 | .family = AF_INET, |
111 | .lock = RW_LOCK_UNLOCKED, | 119 | .lock = RW_LOCK_UNLOCKED, |
120 | .init_flags = xfrm4_init_flags, | ||
112 | .init_tempsel = __xfrm4_init_tempsel, | 121 | .init_tempsel = __xfrm4_init_tempsel, |
113 | .state_lookup = __xfrm4_state_lookup, | 122 | .state_lookup = __xfrm4_state_lookup, |
114 | .find_acq = __xfrm4_find_acq, | 123 | .find_acq = __xfrm4_find_acq, |
diff --git a/net/ipv4/xfrm4_tunnel.c b/net/ipv4/xfrm4_tunnel.c index 413191f585f6..e1fe360ed27a 100644 --- a/net/ipv4/xfrm4_tunnel.c +++ b/net/ipv4/xfrm4_tunnel.c | |||
@@ -84,7 +84,7 @@ static void ipip_err(struct sk_buff *skb, u32 info) | |||
84 | handler->err_handler(skb, &arg); | 84 | handler->err_handler(skb, &arg); |
85 | } | 85 | } |
86 | 86 | ||
87 | static int ipip_init_state(struct xfrm_state *x, void *args) | 87 | static int ipip_init_state(struct xfrm_state *x) |
88 | { | 88 | { |
89 | if (!x->props.mode) | 89 | if (!x->props.mode) |
90 | return -EINVAL; | 90 | return -EINVAL; |