From e4553eddae592b948c9695c9a0002169b0cab6fc Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Tue, 3 May 2005 14:25:13 -0700 Subject: [IPV6]: Include ipv6.h for ipv6_addr_set This patch includes net/ipv6.h from addrconf.h since it needs ipv6_addr_set. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- include/net/addrconf.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/net/addrconf.h b/include/net/addrconf.h index 7af9a13cb9be..f1e5af4be98e 100644 --- a/include/net/addrconf.h +++ b/include/net/addrconf.h @@ -46,6 +46,7 @@ struct prefix_info { #include #include #include +#include #define IN6_ADDR_HSIZE 16 -- cgit v1.2.3 From 526bdb80a23b2e10ed4ccc3fcf309c9118d892d6 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Tue, 3 May 2005 14:26:01 -0700 Subject: [XFRM]: Prevent off-by-one access to xfrm_dispatch Makes the type > XFRM_MSG_MAX check behave correctly to protect access to xfrm_dispatch. Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- include/linux/xfrm.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h index f0df02ae68a4..4d19b9e65317 100644 --- a/include/linux/xfrm.h +++ b/include/linux/xfrm.h @@ -140,8 +140,9 @@ enum { XFRM_MSG_FLUSHPOLICY, #define XFRM_MSG_FLUSHPOLICY XFRM_MSG_FLUSHPOLICY - XFRM_MSG_MAX + __XFRM_MSG_MAX }; +#define XFRM_MSG_MAX (__XFRM_MSG_MAX - 1) struct xfrm_user_tmpl { struct xfrm_id id; -- cgit v1.2.3 From 492b558b3191319cbc859a9e025bc354d336c261 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Tue, 3 May 2005 14:26:40 -0700 Subject: [XFRM]: Cleanup xfrm_msg_min and xfrm_dispatch Converts xfrm_msg_min and xfrm_dispatch to use c99 designated initializers to make greping a little bit easier. Also replaces two hardcoded message type with meaningful names. Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- include/linux/xfrm.h | 2 ++ net/xfrm/xfrm_user.c | 73 ++++++++++++++++++++++++++-------------------------- 2 files changed, 38 insertions(+), 37 deletions(-) (limited to 'include') diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h index 4d19b9e65317..fd2ef742a9fd 100644 --- a/include/linux/xfrm.h +++ b/include/linux/xfrm.h @@ -144,6 +144,8 @@ enum { }; #define XFRM_MSG_MAX (__XFRM_MSG_MAX - 1) +#define XFRM_NR_MSGTYPES (XFRM_MSG_MAX + 1 - XFRM_MSG_BASE) + struct xfrm_user_tmpl { struct xfrm_id id; __u16 family; diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 63661b0fd736..52b5843937c5 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c @@ -855,47 +855,44 @@ static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **x return 0; } -static const int xfrm_msg_min[(XFRM_MSG_MAX + 1 - XFRM_MSG_BASE)] = { - NLMSG_LENGTH(sizeof(struct xfrm_usersa_info)), /* NEW SA */ - NLMSG_LENGTH(sizeof(struct xfrm_usersa_id)), /* DEL SA */ - NLMSG_LENGTH(sizeof(struct xfrm_usersa_id)), /* GET SA */ - NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_info)),/* NEW POLICY */ - NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_id)), /* DEL POLICY */ - NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_id)), /* GET POLICY */ - NLMSG_LENGTH(sizeof(struct xfrm_userspi_info)), /* ALLOC SPI */ - NLMSG_LENGTH(sizeof(struct xfrm_user_acquire)), /* ACQUIRE */ - NLMSG_LENGTH(sizeof(struct xfrm_user_expire)), /* EXPIRE */ - NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_info)),/* UPD POLICY */ - NLMSG_LENGTH(sizeof(struct xfrm_usersa_info)), /* UPD SA */ - NLMSG_LENGTH(sizeof(struct xfrm_user_polexpire)), /* POLEXPIRE */ - NLMSG_LENGTH(sizeof(struct xfrm_usersa_flush)), /* FLUSH SA */ - NLMSG_LENGTH(0), /* FLUSH POLICY */ +#define XMSGSIZE(type) NLMSG_LENGTH(sizeof(struct type)) + +static const int xfrm_msg_min[XFRM_NR_MSGTYPES] = { + [XFRM_MSG_NEWSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_info), + [XFRM_MSG_DELSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_id), + [XFRM_MSG_GETSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_id), + [XFRM_MSG_NEWPOLICY - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_info), + [XFRM_MSG_DELPOLICY - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_id), + [XFRM_MSG_GETPOLICY - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_id), + [XFRM_MSG_ALLOCSPI - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userspi_info), + [XFRM_MSG_ACQUIRE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_acquire), + [XFRM_MSG_EXPIRE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_expire), + [XFRM_MSG_UPDPOLICY - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_info), + [XFRM_MSG_UPDSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_info), + [XFRM_MSG_POLEXPIRE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_polexpire), + [XFRM_MSG_FLUSHSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_flush), + [XFRM_MSG_FLUSHPOLICY - XFRM_MSG_BASE] = NLMSG_LENGTH(0), }; +#undef XMSGSIZE + static struct xfrm_link { int (*doit)(struct sk_buff *, struct nlmsghdr *, void **); int (*dump)(struct sk_buff *, struct netlink_callback *); -} xfrm_dispatch[] = { - { .doit = xfrm_add_sa, }, - { .doit = xfrm_del_sa, }, - { - .doit = xfrm_get_sa, - .dump = xfrm_dump_sa, - }, - { .doit = xfrm_add_policy }, - { .doit = xfrm_get_policy }, - { - .doit = xfrm_get_policy, - .dump = xfrm_dump_policy, - }, - { .doit = xfrm_alloc_userspi }, - {}, - {}, - { .doit = xfrm_add_policy }, - { .doit = xfrm_add_sa, }, - {}, - { .doit = xfrm_flush_sa }, - { .doit = xfrm_flush_policy }, +} xfrm_dispatch[XFRM_NR_MSGTYPES] = { + [XFRM_MSG_NEWSA - XFRM_MSG_BASE] = { .doit = xfrm_add_sa }, + [XFRM_MSG_DELSA - XFRM_MSG_BASE] = { .doit = xfrm_del_sa }, + [XFRM_MSG_GETSA - XFRM_MSG_BASE] = { .doit = xfrm_get_sa, + .dump = xfrm_dump_sa }, + [XFRM_MSG_NEWPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_add_policy }, + [XFRM_MSG_DELPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_get_policy }, + [XFRM_MSG_GETPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_get_policy, + .dump = xfrm_dump_policy }, + [XFRM_MSG_ALLOCSPI - XFRM_MSG_BASE] = { .doit = xfrm_alloc_userspi }, + [XFRM_MSG_UPDPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_add_policy }, + [XFRM_MSG_UPDSA - XFRM_MSG_BASE] = { .doit = xfrm_add_sa }, + [XFRM_MSG_FLUSHSA - XFRM_MSG_BASE] = { .doit = xfrm_flush_sa }, + [XFRM_MSG_FLUSHPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_flush_policy }, }; static int xfrm_done(struct netlink_callback *cb) @@ -931,7 +928,9 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *err return -1; } - if ((type == 2 || type == 5) && (nlh->nlmsg_flags & NLM_F_DUMP)) { + if ((type == (XFRM_MSG_GETSA - XFRM_MSG_BASE) || + type == (XFRM_MSG_GETPOLICY - XFRM_MSG_BASE)) && + (nlh->nlmsg_flags & NLM_F_DUMP)) { u32 rlen; if (link->dump == NULL) -- cgit v1.2.3 From d775fc09f16f4b88cd0373006b112c4772589778 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Tue, 3 May 2005 14:27:35 -0700 Subject: [RTNETLINK] Fix RTM_MAX to represent the maximum valid message type RTM_MAX is currently set to the maximum reserverd message type plus one thus being the cause of two bugs for new types being assigned a) given the new family registers only the NEW command in its reserved block the array size for per family entries is calculated one entry short and b) given the new family registers all commands RTM_MAX would point to the first entry of the block following this one and the rtnetlink receive path would accept a message type for a nonexisting family. This patch changes RTM_MAX to point to the maximum valid message type by aligning it to the start of the next block and subtracting one. Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- include/linux/rtnetlink.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h index 32e52769a00b..d607219af6ac 100644 --- a/include/linux/rtnetlink.h +++ b/include/linux/rtnetlink.h @@ -89,8 +89,8 @@ enum { RTM_GETANYCAST = 62, #define RTM_GETANYCAST RTM_GETANYCAST - RTM_MAX, -#define RTM_MAX RTM_MAX + __RTM_MAX, +#define RTM_MAX (((__RTM_MAX + 3) & ~3) - 1) }; /* -- cgit v1.2.3 From f90a0a74b864fdc46737614f03b8868f4f31e3bf Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Tue, 3 May 2005 14:29:00 -0700 Subject: [RTNETLINK] Fix & cleanup rtm_min/rtm_max Converts rtm_min and rtm_max arrays to use c99 designated initializers for easier insertion of new message families. RTM_GETMULTICAST and RTM_GETANYCAST did not have the minimal message size specified which means that the netlink message was parsed for routing attributes starting from the header. Adds the proper minimal message sizes for these messages (netlink header + common rtnetlink header) to fix this issue. Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- include/linux/rtnetlink.h | 2 ++ net/core/rtnetlink.c | 39 +++++++++++++++++++++------------------ 2 files changed, 23 insertions(+), 18 deletions(-) (limited to 'include') diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h index d607219af6ac..1ecaea74d55a 100644 --- a/include/linux/rtnetlink.h +++ b/include/linux/rtnetlink.h @@ -93,6 +93,8 @@ enum { #define RTM_MAX (((__RTM_MAX + 3) & ~3) - 1) }; +#define RTM_FAM(cmd) (((cmd) - RTM_BASE) >> 2) + /* Generic structure for encapsulation of optional route information. It is reminiscent of sockaddr, but with sa_family replaced diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index d8c198e42f90..58a981806268 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -88,28 +88,31 @@ struct rtnetlink_link * rtnetlink_links[NPROTO]; static const int rtm_min[(RTM_MAX+1-RTM_BASE)/4] = { - NLMSG_LENGTH(sizeof(struct ifinfomsg)), - NLMSG_LENGTH(sizeof(struct ifaddrmsg)), - NLMSG_LENGTH(sizeof(struct rtmsg)), - NLMSG_LENGTH(sizeof(struct ndmsg)), - NLMSG_LENGTH(sizeof(struct rtmsg)), - NLMSG_LENGTH(sizeof(struct tcmsg)), - NLMSG_LENGTH(sizeof(struct tcmsg)), - NLMSG_LENGTH(sizeof(struct tcmsg)), - NLMSG_LENGTH(sizeof(struct tcamsg)) + [RTM_FAM(RTM_NEWLINK)] = NLMSG_LENGTH(sizeof(struct ifinfomsg)), + [RTM_FAM(RTM_NEWADDR)] = NLMSG_LENGTH(sizeof(struct ifaddrmsg)), + [RTM_FAM(RTM_NEWROUTE)] = NLMSG_LENGTH(sizeof(struct rtmsg)), + [RTM_FAM(RTM_NEWNEIGH)] = NLMSG_LENGTH(sizeof(struct ndmsg)), + [RTM_FAM(RTM_NEWRULE)] = NLMSG_LENGTH(sizeof(struct rtmsg)), + [RTM_FAM(RTM_NEWQDISC)] = NLMSG_LENGTH(sizeof(struct tcmsg)), + [RTM_FAM(RTM_NEWTCLASS)] = NLMSG_LENGTH(sizeof(struct tcmsg)), + [RTM_FAM(RTM_NEWTFILTER)] = NLMSG_LENGTH(sizeof(struct tcmsg)), + [RTM_FAM(RTM_NEWACTION)] = NLMSG_LENGTH(sizeof(struct tcamsg)), + [RTM_FAM(RTM_NEWPREFIX)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)), + [RTM_FAM(RTM_GETMULTICAST)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)), + [RTM_FAM(RTM_GETANYCAST)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)), }; static const int rta_max[(RTM_MAX+1-RTM_BASE)/4] = { - IFLA_MAX, - IFA_MAX, - RTA_MAX, - NDA_MAX, - RTA_MAX, - TCA_MAX, - TCA_MAX, - TCA_MAX, - TCAA_MAX + [RTM_FAM(RTM_NEWLINK)] = IFLA_MAX, + [RTM_FAM(RTM_NEWADDR)] = IFA_MAX, + [RTM_FAM(RTM_NEWROUTE)] = RTA_MAX, + [RTM_FAM(RTM_NEWNEIGH)] = NDA_MAX, + [RTM_FAM(RTM_NEWRULE)] = RTA_MAX, + [RTM_FAM(RTM_NEWQDISC)] = TCA_MAX, + [RTM_FAM(RTM_NEWTCLASS)] = TCA_MAX, + [RTM_FAM(RTM_NEWTFILTER)] = TCA_MAX, + [RTM_FAM(RTM_NEWACTION)] = TCAA_MAX, }; void __rta_fill(struct sk_buff *skb, int attrtype, int attrlen, const void *data) -- cgit v1.2.3 From db46edc6d3b66bf708a8f23a9aa89f63a49ebe33 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Tue, 3 May 2005 14:29:39 -0700 Subject: [RTNETLINK] Cleanup rtnetlink_link tables Converts remaining rtnetlink_link tables to use c99 designated initializers to make greping a little bit easier. Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- include/linux/rtnetlink.h | 2 ++ net/core/rtnetlink.c | 6 +++--- net/decnet/dn_dev.c | 25 +++++++++++++------------ net/ipv4/devinet.c | 21 +++++++++++---------- net/ipv6/addrconf.c | 2 +- 5 files changed, 30 insertions(+), 26 deletions(-) (limited to 'include') diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h index 1ecaea74d55a..91ac97c20777 100644 --- a/include/linux/rtnetlink.h +++ b/include/linux/rtnetlink.h @@ -93,6 +93,8 @@ enum { #define RTM_MAX (((__RTM_MAX + 3) & ~3) - 1) }; +#define RTM_NR_MSGTYPES (RTM_MAX + 1 - RTM_BASE) +#define RTM_NR_FAMILIES (RTM_NR_MSGTYPES >> 2) #define RTM_FAM(cmd) (((cmd) - RTM_BASE) >> 2) /* diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 58a981806268..5fb70cfa1085 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -86,7 +86,7 @@ struct sock *rtnl; struct rtnetlink_link * rtnetlink_links[NPROTO]; -static const int rtm_min[(RTM_MAX+1-RTM_BASE)/4] = +static const int rtm_min[RTM_NR_FAMILIES] = { [RTM_FAM(RTM_NEWLINK)] = NLMSG_LENGTH(sizeof(struct ifinfomsg)), [RTM_FAM(RTM_NEWADDR)] = NLMSG_LENGTH(sizeof(struct ifaddrmsg)), @@ -102,7 +102,7 @@ static const int rtm_min[(RTM_MAX+1-RTM_BASE)/4] = [RTM_FAM(RTM_GETANYCAST)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)), }; -static const int rta_max[(RTM_MAX+1-RTM_BASE)/4] = +static const int rta_max[RTM_NR_FAMILIES] = { [RTM_FAM(RTM_NEWLINK)] = IFLA_MAX, [RTM_FAM(RTM_NEWADDR)] = IFA_MAX, @@ -641,7 +641,7 @@ static void rtnetlink_rcv(struct sock *sk, int len) } while (rtnl && rtnl->sk_receive_queue.qlen); } -static struct rtnetlink_link link_rtnetlink_table[RTM_MAX-RTM_BASE+1] = +static struct rtnetlink_link link_rtnetlink_table[RTM_NR_MSGTYPES] = { [RTM_GETLINK - RTM_BASE] = { .dumpit = rtnetlink_dump_ifinfo }, [RTM_SETLINK - RTM_BASE] = { .doit = do_setlink }, diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c index c2a0346f423b..e6e23eb14428 100644 --- a/net/decnet/dn_dev.c +++ b/net/decnet/dn_dev.c @@ -1411,21 +1411,22 @@ static struct file_operations dn_dev_seq_fops = { #endif /* CONFIG_PROC_FS */ -static struct rtnetlink_link dnet_rtnetlink_table[RTM_MAX-RTM_BASE+1] = +static struct rtnetlink_link dnet_rtnetlink_table[RTM_NR_MSGTYPES] = { - [4] = { .doit = dn_dev_rtm_newaddr, }, - [5] = { .doit = dn_dev_rtm_deladdr, }, - [6] = { .dumpit = dn_dev_dump_ifaddr, }, - + [RTM_NEWADDR - RTM_BASE] = { .doit = dn_dev_rtm_newaddr, }, + [RTM_DELADDR - RTM_BASE] = { .doit = dn_dev_rtm_deladdr, }, + [RTM_GETADDR - RTM_BASE] = { .dumpit = dn_dev_dump_ifaddr, }, #ifdef CONFIG_DECNET_ROUTER - [8] = { .doit = dn_fib_rtm_newroute, }, - [9] = { .doit = dn_fib_rtm_delroute, }, - [10] = { .doit = dn_cache_getroute, .dumpit = dn_fib_dump, }, - [16] = { .doit = dn_fib_rtm_newrule, }, - [17] = { .doit = dn_fib_rtm_delrule, }, - [18] = { .dumpit = dn_fib_dump_rules, }, + [RTM_NEWROUTE - RTM_BASE] = { .doit = dn_fib_rtm_newroute, }, + [RTM_DELROUTE - RTM_BASE] = { .doit = dn_fib_rtm_delroute, }, + [RTM_GETROUTE - RTM_BASE] = { .doit = dn_cache_getroute, + .dumpit = dn_fib_dump, }, + [RTM_NEWRULE - RTM_BASE] = { .doit = dn_fib_rtm_newrule, }, + [RTM_DELRULE - RTM_BASE] = { .doit = dn_fib_rtm_delrule, }, + [RTM_GETRULE - RTM_BASE] = { .dumpit = dn_fib_dump_rules, }, #else - [10] = { .doit = dn_cache_getroute, .dumpit = dn_cache_dump, }, + [RTM_GETROUTE - RTM_BASE] = { .doit = dn_cache_getroute, + .dumpit = dn_cache_dump, #endif }; diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index eea7ef010776..abbc6d5c183e 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -1107,17 +1107,18 @@ static void rtmsg_ifa(int event, struct in_ifaddr* ifa) } } -static struct rtnetlink_link inet_rtnetlink_table[RTM_MAX - RTM_BASE + 1] = { - [4] = { .doit = inet_rtm_newaddr, }, - [5] = { .doit = inet_rtm_deladdr, }, - [6] = { .dumpit = inet_dump_ifaddr, }, - [8] = { .doit = inet_rtm_newroute, }, - [9] = { .doit = inet_rtm_delroute, }, - [10] = { .doit = inet_rtm_getroute, .dumpit = inet_dump_fib, }, +static struct rtnetlink_link inet_rtnetlink_table[RTM_NR_MSGTYPES] = { + [RTM_NEWADDR - RTM_BASE] = { .doit = inet_rtm_newaddr, }, + [RTM_DELADDR - RTM_BASE] = { .doit = inet_rtm_deladdr, }, + [RTM_GETADDR - RTM_BASE] = { .dumpit = inet_dump_ifaddr, }, + [RTM_NEWROUTE - RTM_BASE] = { .doit = inet_rtm_newroute, }, + [RTM_DELROUTE - RTM_BASE] = { .doit = inet_rtm_delroute, }, + [RTM_GETROUTE - RTM_BASE] = { .doit = inet_rtm_getroute, + .dumpit = inet_dump_fib, }, #ifdef CONFIG_IP_MULTIPLE_TABLES - [16] = { .doit = inet_rtm_newrule, }, - [17] = { .doit = inet_rtm_delrule, }, - [18] = { .dumpit = inet_dump_rules, }, + [RTM_NEWRULE - RTM_BASE] = { .doit = inet_rtm_newrule, }, + [RTM_DELRULE - RTM_BASE] = { .doit = inet_rtm_delrule, }, + [RTM_GETRULE - RTM_BASE] = { .dumpit = inet_dump_rules, }, #endif }; diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 7196ac2f2d16..7744a2592693 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -3076,7 +3076,7 @@ static void inet6_prefix_notify(int event, struct inet6_dev *idev, netlink_broadcast(rtnl, skb, 0, RTMGRP_IPV6_PREFIX, GFP_ATOMIC); } -static struct rtnetlink_link inet6_rtnetlink_table[RTM_MAX - RTM_BASE + 1] = { +static struct rtnetlink_link inet6_rtnetlink_table[RTM_NR_MSGTYPES] = { [RTM_GETLINK - RTM_BASE] = { .dumpit = inet6_dump_ifinfo, }, [RTM_NEWADDR - RTM_BASE] = { .doit = inet6_rtm_newaddr, }, [RTM_DELADDR - RTM_BASE] = { .doit = inet6_rtm_deladdr, }, -- cgit v1.2.3 From 9dfa277f88388a94993b121db46b80df66f48d9e Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Tue, 3 May 2005 14:41:18 -0700 Subject: [PKT_SCHED]: Fix range in PSCHED_TDIFF_SAFE to 0..bound Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- include/net/pkt_sched.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h index 7352e455053c..fcb05a387dbe 100644 --- a/include/net/pkt_sched.h +++ b/include/net/pkt_sched.h @@ -157,7 +157,8 @@ psched_tod_diff(int delta_sec, int bound) case 1: \ __delta += 1000000; \ case 0: \ - __delta = abs(__delta); \ + if (__delta > bound || __delta < 0) \ + __delta = bound; \ } \ __delta; \ }) -- cgit v1.2.3 From aabc9761b69f1bfa30a78f7005be95cc9cc06175 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Tue, 3 May 2005 16:27:10 -0700 Subject: [IPSEC]: Store idev entries I found a bug that stopped IPsec/IPv6 from working. About a month ago IPv6 started using rt6i_idev->dev on the cached socket dst entries. If the cached socket dst entry is IPsec, then rt6i_idev will be NULL. Since we want to look at the rt6i_idev of the original route in this case, the easiest fix is to store rt6i_idev in the IPsec dst entry just as we do for a number of other IPv6 route attributes. Unfortunately this means that we need some new code to handle the references to rt6i_idev. That's why this patch is bigger than it would otherwise be. I've also done the same thing for IPv4 since it is conceivable that once these idev attributes start getting used for accounting, we probably need to dereference them for IPv4 IPsec entries too. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- include/net/xfrm.h | 10 ++++++++++ net/ipv4/xfrm4_policy.c | 42 ++++++++++++++++++++++++++++++++++++++++++ net/ipv6/xfrm6_policy.c | 43 +++++++++++++++++++++++++++++++++++++++++++ net/xfrm/xfrm_policy.c | 25 ++----------------------- 4 files changed, 97 insertions(+), 23 deletions(-) (limited to 'include') diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 73e9a8ca3d3b..e142a256d5dc 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -1,6 +1,7 @@ #ifndef _NET_XFRM_H #define _NET_XFRM_H +#include #include #include #include @@ -516,6 +517,15 @@ struct xfrm_dst u32 child_mtu_cached; }; +static inline void xfrm_dst_destroy(struct xfrm_dst *xdst) +{ + dst_release(xdst->route); + if (likely(xdst->u.dst.xfrm)) + xfrm_state_put(xdst->u.dst.xfrm); +} + +extern void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev); + /* Decapsulation state, used by the input to store data during * decapsulation procedure, to be used later (during the policy * check diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index 7fe2afd2e669..b2b60f3e9cdd 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c @@ -8,7 +8,10 @@ * */ +#include +#include #include +#include #include #include @@ -152,6 +155,8 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int x->u.rt.rt_dst = rt0->rt_dst; x->u.rt.rt_gateway = rt->rt_gateway; x->u.rt.rt_spec_dst = rt0->rt_spec_dst; + x->u.rt.idev = rt0->idev; + in_dev_hold(rt0->idev); header_len -= x->u.dst.xfrm->props.header_len; trailer_len -= x->u.dst.xfrm->props.trailer_len; } @@ -243,11 +248,48 @@ static void xfrm4_update_pmtu(struct dst_entry *dst, u32 mtu) path->ops->update_pmtu(path, mtu); } +static void xfrm4_dst_destroy(struct dst_entry *dst) +{ + struct xfrm_dst *xdst = (struct xfrm_dst *)dst; + + if (likely(xdst->u.rt.idev)) + in_dev_put(xdst->u.rt.idev); + xfrm_dst_destroy(xdst); +} + +static void xfrm4_dst_ifdown(struct dst_entry *dst, struct net_device *dev, + int unregister) +{ + struct xfrm_dst *xdst; + + if (!unregister) + return; + + xdst = (struct xfrm_dst *)dst; + if (xdst->u.rt.idev->dev == dev) { + struct in_device *loopback_idev = in_dev_get(&loopback_dev); + BUG_ON(!loopback_idev); + + do { + in_dev_put(xdst->u.rt.idev); + xdst->u.rt.idev = loopback_idev; + in_dev_hold(loopback_idev); + xdst = (struct xfrm_dst *)xdst->u.dst.child; + } while (xdst->u.dst.xfrm); + + __in_dev_put(loopback_idev); + } + + xfrm_dst_ifdown(dst, dev); +} + static struct dst_ops xfrm4_dst_ops = { .family = AF_INET, .protocol = __constant_htons(ETH_P_IP), .gc = xfrm4_garbage_collect, .update_pmtu = xfrm4_update_pmtu, + .destroy = xfrm4_dst_destroy, + .ifdown = xfrm4_dst_ifdown, .gc_thresh = 1024, .entry_size = sizeof(struct xfrm_dst), }; diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index 8a4f37de4d2d..4429b1a1fe5f 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c @@ -11,7 +11,11 @@ * */ +#include +#include #include +#include +#include #include #include #include @@ -166,6 +170,8 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int memcpy(&x->u.rt6.rt6i_gateway, &rt0->rt6i_gateway, sizeof(x->u.rt6.rt6i_gateway)); x->u.rt6.rt6i_dst = rt0->rt6i_dst; x->u.rt6.rt6i_src = rt0->rt6i_src; + x->u.rt6.rt6i_idev = rt0->rt6i_idev; + in6_dev_hold(rt0->rt6i_idev); header_len -= x->u.dst.xfrm->props.header_len; trailer_len -= x->u.dst.xfrm->props.trailer_len; } @@ -251,11 +257,48 @@ static void xfrm6_update_pmtu(struct dst_entry *dst, u32 mtu) path->ops->update_pmtu(path, mtu); } +static void xfrm6_dst_destroy(struct dst_entry *dst) +{ + struct xfrm_dst *xdst = (struct xfrm_dst *)dst; + + if (likely(xdst->u.rt6.rt6i_idev)) + in6_dev_put(xdst->u.rt6.rt6i_idev); + xfrm_dst_destroy(xdst); +} + +static void xfrm6_dst_ifdown(struct dst_entry *dst, struct net_device *dev, + int unregister) +{ + struct xfrm_dst *xdst; + + if (!unregister) + return; + + xdst = (struct xfrm_dst *)dst; + if (xdst->u.rt6.rt6i_idev->dev == dev) { + struct inet6_dev *loopback_idev = in6_dev_get(&loopback_dev); + BUG_ON(!loopback_idev); + + do { + in6_dev_put(xdst->u.rt6.rt6i_idev); + xdst->u.rt6.rt6i_idev = loopback_idev; + in6_dev_hold(loopback_idev); + xdst = (struct xfrm_dst *)xdst->u.dst.child; + } while (xdst->u.dst.xfrm); + + __in6_dev_put(loopback_idev); + } + + xfrm_dst_ifdown(dst, dev); +} + static struct dst_ops xfrm6_dst_ops = { .family = AF_INET6, .protocol = __constant_htons(ETH_P_IPV6), .gc = xfrm6_garbage_collect, .update_pmtu = xfrm6_update_pmtu, + .destroy = xfrm6_dst_destroy, + .ifdown = xfrm6_dst_ifdown, .gc_thresh = 1024, .entry_size = sizeof(struct xfrm_dst), }; diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 80828078733d..55ed979db144 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -1028,30 +1028,15 @@ static int stale_bundle(struct dst_entry *dst) return !xfrm_bundle_ok((struct xfrm_dst *)dst, NULL, AF_UNSPEC); } -static void xfrm_dst_destroy(struct dst_entry *dst) +void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev) { - struct xfrm_dst *xdst = (struct xfrm_dst *)dst; - - dst_release(xdst->route); - - if (!dst->xfrm) - return; - xfrm_state_put(dst->xfrm); - dst->xfrm = NULL; -} - -static void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev, - int unregister) -{ - if (!unregister) - return; - while ((dst = dst->child) && dst->xfrm && dst->dev == dev) { dst->dev = &loopback_dev; dev_hold(&loopback_dev); dev_put(dev); } } +EXPORT_SYMBOL(xfrm_dst_ifdown); static void xfrm_link_failure(struct sk_buff *skb) { @@ -1262,10 +1247,6 @@ int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo) dst_ops->kmem_cachep = xfrm_dst_cache; if (likely(dst_ops->check == NULL)) dst_ops->check = xfrm_dst_check; - if (likely(dst_ops->destroy == NULL)) - dst_ops->destroy = xfrm_dst_destroy; - if (likely(dst_ops->ifdown == NULL)) - dst_ops->ifdown = xfrm_dst_ifdown; if (likely(dst_ops->negative_advice == NULL)) dst_ops->negative_advice = xfrm_negative_advice; if (likely(dst_ops->link_failure == NULL)) @@ -1297,8 +1278,6 @@ int xfrm_policy_unregister_afinfo(struct xfrm_policy_afinfo *afinfo) xfrm_policy_afinfo[afinfo->family] = NULL; dst_ops->kmem_cachep = NULL; dst_ops->check = NULL; - dst_ops->destroy = NULL; - dst_ops->ifdown = NULL; dst_ops->negative_advice = NULL; dst_ops->link_failure = NULL; dst_ops->get_mss = NULL; -- cgit v1.2.3