diff options
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/af_inet6.c | 10 | ||||
-rw-r--r-- | net/ipv6/exthdrs.c | 64 |
2 files changed, 46 insertions, 28 deletions
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 614f3d905dd1..442c298c1d7c 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -859,10 +859,11 @@ static int __init inet6_init(void) goto addrconf_fail; /* Init v6 extension headers. */ - ipv6_rthdr_init(); + err = ipv6_exthdrs_init(); + if (err) + goto ipv6_exthdrs_fail; + ipv6_frag_init(); - ipv6_nodata_init(); - ipv6_destopt_init(); /* Init v6 transport protocols. */ udpv6_init(); @@ -874,6 +875,8 @@ static int __init inet6_init(void) out: return err; +ipv6_exthdrs_fail: + addrconf_cleanup(); addrconf_fail: ip6_flowlabel_cleanup(); ip6_flowlabel_fail: @@ -932,6 +935,7 @@ static void __exit inet6_exit(void) /* Cleanup code parts. */ ipv6_packet_cleanup(); + ipv6_exthdrs_exit(); addrconf_cleanup(); ip6_flowlabel_cleanup(); ip6_route_cleanup(); diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index cee06b1655c1..2df34ed276f1 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c @@ -308,28 +308,6 @@ static int ipv6_destopt_rcv(struct sk_buff *skb) return -1; } -static struct inet6_protocol destopt_protocol = { - .handler = ipv6_destopt_rcv, - .flags = INET6_PROTO_NOPOLICY | INET6_PROTO_GSO_EXTHDR, -}; - -void __init ipv6_destopt_init(void) -{ - if (inet6_add_protocol(&destopt_protocol, IPPROTO_DSTOPTS) < 0) - printk(KERN_ERR "ipv6_destopt_init: Could not register protocol\n"); -} - -static struct inet6_protocol nodata_protocol = { - .handler = dst_discard, - .flags = INET6_PROTO_NOPOLICY, -}; - -void __init ipv6_nodata_init(void) -{ - if (inet6_add_protocol(&nodata_protocol, IPPROTO_NONE) < 0) - printk(KERN_ERR "ipv6_nodata_init: Could not register protocol\n"); -} - /******************************** Routing header. ********************************/ @@ -527,12 +505,48 @@ static struct inet6_protocol rthdr_protocol = { .flags = INET6_PROTO_NOPOLICY | INET6_PROTO_GSO_EXTHDR, }; -void __init ipv6_rthdr_init(void) +static struct inet6_protocol destopt_protocol = { + .handler = ipv6_destopt_rcv, + .flags = INET6_PROTO_NOPOLICY | INET6_PROTO_GSO_EXTHDR, +}; + +static struct inet6_protocol nodata_protocol = { + .handler = dst_discard, + .flags = INET6_PROTO_NOPOLICY, +}; + +int __init ipv6_exthdrs_init(void) { - if (inet6_add_protocol(&rthdr_protocol, IPPROTO_ROUTING) < 0) - printk(KERN_ERR "ipv6_rthdr_init: Could not register protocol\n"); + int ret; + + ret = inet6_add_protocol(&rthdr_protocol, IPPROTO_ROUTING); + if (ret) + goto out; + + ret = inet6_add_protocol(&destopt_protocol, IPPROTO_DSTOPTS); + if (ret) + goto out_rthdr; + + ret = inet6_add_protocol(&nodata_protocol, IPPROTO_NONE); + if (ret) + goto out_destopt; + +out: + return ret; +out_rthdr: + inet6_del_protocol(&rthdr_protocol, IPPROTO_ROUTING); +out_destopt: + inet6_del_protocol(&destopt_protocol, IPPROTO_DSTOPTS); + goto out; }; +void ipv6_exthdrs_exit(void) +{ + inet6_del_protocol(&nodata_protocol, IPPROTO_NONE); + inet6_del_protocol(&destopt_protocol, IPPROTO_DSTOPTS); + inet6_del_protocol(&rthdr_protocol, IPPROTO_ROUTING); +} + /********************************** Hop-by-hop options. **********************************/ |