diff options
author | Daniel Lezcano <dlezcano@fr.ibm.com> | 2007-12-11 02:23:54 -0800 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 14:57:10 -0800 |
commit | 248b238dc960a42aa235057ba0a51a98ae2b0f0d (patch) | |
tree | 0c655bde3e6a9ad24491fe3ec4edaba1bf9053f2 | |
parent | 0a3e78ac2c555441f5bc00588070058533bc8d6b (diff) | |
download | kernel_samsung_smdk4412-248b238dc960a42aa235057ba0a51a98ae2b0f0d.zip kernel_samsung_smdk4412-248b238dc960a42aa235057ba0a51a98ae2b0f0d.tar.gz kernel_samsung_smdk4412-248b238dc960a42aa235057ba0a51a98ae2b0f0d.tar.bz2 |
[IPV6]: make extended headers to return an error at initialization
This patch factorize the code for the differents init functions for rthdr,
nodata, destopt in a single function exthdrs_init.
This function returns an error so the af_inet6 module can check correctly
the initialization.
Signed-off-by: Daniel Lezcano <dlezcano@fr.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/net/transp_v6.h | 5 | ||||
-rw-r--r-- | net/ipv6/af_inet6.c | 10 | ||||
-rw-r--r-- | net/ipv6/exthdrs.c | 64 |
3 files changed, 48 insertions, 31 deletions
diff --git a/include/net/transp_v6.h b/include/net/transp_v6.h index 409da3a..610b1bb 100644 --- a/include/net/transp_v6.h +++ b/include/net/transp_v6.h @@ -17,10 +17,9 @@ extern struct proto tcpv6_prot; struct flowi; /* extention headers */ -extern void ipv6_rthdr_init(void); +extern int ipv6_exthdrs_init(void); +extern void ipv6_exthdrs_exit(void); extern void ipv6_frag_init(void); -extern void ipv6_nodata_init(void); -extern void ipv6_destopt_init(void); /* transport protocols */ extern void rawv6_init(void); diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 614f3d9..442c298 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 cee06b1..2df34ed 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. **********************************/ |