Multiple IPV6 Routing Tables & Policy Routing
Subsystems (3)
PATCH 1/1 Multiple IPV6 Routing Tables & Policy Routing
Hello,
This patchset implements multiple IPv6 routing tables and policy routing. Even though the code is almost rewritten entirely the work is based on the MIPL patch found on mobile-ipv6.org which is being jointly developed by Helsinki University of Technology (HUT) and the USAGI/WIDE Project.
Reference counting on routing tables was removed to decrease the number of required atomic operations during route lookup.
The tables are now organized in a hashtable to prepare for the change in supporting more than 255 tables.
Matching sources address in policy rules is no longer dependant on CONFIG_SUBTREES.
Git tree with changes:
master.kernel.org:/pub/scm/linux/kernel/git/tgraf/net-2.6.19-mrt.git
include/linux/fib_rules.h | 60 ++++ include/linux/rtnetlink.h | 2 include/net/fib_rules.h | 90 +++++++ include/net/ip6_fib.h | 46 +++ include/net/ip6_route.h | 8 + include/net/ip_fib.h | 14 + net/Kconfig | 3 net/core/Makefile | 1 net/core/fib_rules.c | 416 +++++++++++++++++++++++++++++++ net/core/rtnetlink.c | 9 + net/ipv4/Kconfig | 1 net/ipv4/devinet.c | 4 net/ipv4/fib_frontend.c | 2 net/ipv4/fib_rules.c | 613 ++++++++++++++++++--------------------------- net/ipv6/Kconfig | 7 + net/ipv6/Makefile | 1 net/ipv6/addrconf.c | 7 - net/ipv6/fib6_rules.c | 251 ++++++++++++++++++ net/ipv6/ip6_fib.c | 143 ++++++++++ net/ipv6/route.c | 442 +++++++++++++++++++++++--------- 20 files changed, 1597 insertions(+), 523 deletions(-
PATCH 1/5 : Remove ndiscs rt6_lock dependency
(Ab)using rt6_lock wouldn't work anymore if rt6_lock is converted into a per table lock.
net/ipv6/route.c +11 -5
@@ -745,8 +745,6 @@ static void ip6_rt_update_pmtu(struct ds } } -/* Protected by rt6_lock. */ -static struct dst_entry *ndisc_dst_gc_list;static int ipv6_get_mtu (struct net_device *dev);static inline unsigned int ipv6_advmss (unsigned int mtu)
@@ -767,6 +765,9 @@ static inline unsigned int ipv6_advmss(ureturn mtu; } +static struct dst_entry *ndisc_dst_gc_list; +DEFINE_SPINLOCK (ndisc_lock); + struct dst_entry *ndisc_dst_alloc(struct net_device *dev, struct neighbour *neigh, struct in6_addr *addr,
@@ -807,10 +808,10 @@ struct dst_entry *ndisc_dst_alloc(struct rt->rt6i_dst.plen =128 ;#endif -write_lock_bh (&rt6_lock); +spin_lock_bh (&ndisc_lock); rt->u.dst.next = ndisc_dst_gc_list; ndisc_dst_gc_list = &rt->u.dst; -write_unlock_bh (&rt6_lock); +spin_unlock_bh (&ndisc_lock);fib6_force_start_gc ();
@@ -824,8 +825,11 @@ int ndisc_dst_gc(int *more)int freed; next =NULL ; + freed =0 ; + +spin_lock_bh (&ndisc_lock); pprev = &ndisc_dst_gc_list; - freed =0 ; +while ((dst = *pprev) !=NULL ) {if (!atomic_read (&dst->__refcnt)) { *pprev = dst->next;
@@ -837,6 +841,8 @@ int ndisc_dst_gc(int *more) } } +spin_unlock_bh (&ndisc_lock); +return freed; }
PATCH 2/5 : Multiple Routing Tables
In reply to Thomas GrafAdds the framework to support multiple IPv6 routing tables. Currently all automatically generated routes are put into the same table. This could be changed at a later point after considering the produced locking overhead.
include/net/ip6_fib.h +38 -1
@@ -51,6 +51,8 @@ struct rt6keyint plen; }; +struct fib6_table ; + struct rt6_info { union {
@@ -71,6 +73,7 @@ struct rt6_infou32 rt6i_flags;u32 rt6i_metric;atomic_t rt6i_ref; +struct fib6_table *rt6i_table;struct rt6key rt6i_dst;struct rt6key rt6i_src;
@@ -143,12 +146,43 @@ struct rt6_statistics {typedef void (*f_pnode )(struct fib6_node *fn,void *); -extern struct fib6_node ip6_routing_table; +struct fib6_table { +struct hlist_node tb6_hlist; +u32 tb6_id; +rwlock_t tb6_lock; +struct fib6_node tb6_root; +}; + +#define RT6_TABLE_UNSPEC RT_TABLE_UNSPEC +#define RT6_TABLE_MAIN RT_TABLE_MAIN +#define RT6_TABLE_LOCAL RT6_TABLE_MAIN +#define RT6_TABLE_DFLT RT6_TABLE_MAIN +#define RT6_TABLE_INFO RT6_TABLE_MAIN +#define RT6_TABLE_PREFIX RT6_TABLE_MAIN + +#ifdef CONFIG_IPV6_MULTIPLE_TABLES +#define FIB6_TABLE_MIN 1 +#define FIB6_TABLE_MAX RT_TABLE_MAX +#else +#define FIB6_TABLE_MIN RT_TABLE_MAIN +#define FIB6_TABLE_MAX FIB6_TABLE_MIN +#endif + +#define RT6_F_STRICT 1 +#define RT6_F_HAS_SADDR 2 + +typedef struct rt6_info *(*pol_lookup_t )(struct fib6_table *, +struct flowi *,int );/* * exported functions */ +extern struct fib6_table *fib6_get_table (u32 id); +extern struct fib6_table *fib6_new_table (u32 id); +extern struct dst_entry *fib6_rule_lookup (struct flowi *fl,int flags, +pol_lookup_t lookup); +extern struct fib6_node *fib6_lookup (struct fib6_node *root,struct in6_addr *daddr,struct in6_addr *saddr);
@@ -161,6 +195,9 @@ extern void fib6_clean_tree(struct fibint (*func)(struct rt6_info *,void *arg), int prune, void *arg); +extern void fib6_clean_all (int (*func)(struct rt6_info *,void *arg), +int prune,void *arg); +extern int fib6_walk (struct fib6_walker_t *w);extern int fib6_walk_continue (struct fib6_walker_t *w);
net/ipv6/ip6_fib.c +140 -4
175 lines not on this page · raw message
net/ipv6/route.c +254 -130
724 lines not on this page · raw message
net/ipv6/Kconfig +6 -0
@@ -135,3 +135,9 @@ config IPV6_TUNNEL If unsure, say N. +config IPV6_MULTIPLE_TABLES + bool "IPv6: Multiple Routing Tables" + depends on IPV6 && EXPERIMENTAL + ---help--- + Support multiple routing tables. +
include/net/ip6_route.h +2 -1
@@ -58,7 +58,8 @@ extern int ipv6_route_ioctl(unsigned iextern int ip6_route_add (struct in6_rtmsg *rtmsg,struct nlmsghdr *,void *rtattr, -struct netlink_skb_parms *req); +struct netlink_skb_parms *req, +u32 table_id); extern int ip6_ins_rt(struct rt6_info *, struct nlmsghdr *, void *rtattr,
net/ipv6/addrconf.c +3 -3
@@ -1525,7 +1525,7 @@ addrconf_prefix_route(struct in6_addr *pif (dev->type ==ARPHRD_SIT && (dev->flags&IFF_POINTOPOINT )) rtmsg.rtmsg_flags |=RTF_NONEXTHOP ; -ip6_route_add (&rtmsg,NULL ,NULL ,NULL ); +ip6_route_add (&rtmsg,NULL ,NULL ,NULL ,RT6_TABLE_PREFIX ); }/* Create "default" multicast route to the interface */
@@ -1542,7 +1542,7 @@ static void addrconf_add_mroute(struct n rtmsg.rtmsg_ifindex = dev->ifindex; rtmsg.rtmsg_flags =RTF_UP ; rtmsg.rtmsg_type =RTMSG_NEWROUTE ; -ip6_route_add (&rtmsg,NULL ,NULL ,NULL ); +ip6_route_add (&rtmsg,NULL ,NULL ,NULL ,RT6_TABLE_LOCAL ); }static void sit_route_add (struct net_device *dev)
@@ -1559,7 +1559,7 @@ static void sit_route_add(struct net_dev rtmsg.rtmsg_flags =RTF_UP |RTF_NONEXTHOP ; rtmsg.rtmsg_ifindex = dev->ifindex; -ip6_route_add (&rtmsg,NULL ,NULL ,NULL ); +ip6_route_add (&rtmsg,NULL ,NULL ,NULL ,RT6_TABLE_MAIN ); }static void addrconf_add_lroute (struct net_device *dev)
Re: [PATCH 2/5] [IPV6]: Multiple Routing Tables
net/ipv6/route.c static int rt6_fill_node(struct sk_buff · line 1850
Quoted 13 lines · Thomas Graf
Index:
net-2.6.19/net/ipv6/route.c
===================================================================net/ipv6/route.c +4
-0@@ -1750,6 +1843,10 @@ static int rt6_fill_node(struct sk_buff rtm->rtm_dst_len = rt->rt6i_dst.plen; rtm->rtm_src_len = rt->rt6i_src.plen; rtm->rtm_tos =0 ; +if (rt->rt6i_table) + rtm->rtm_table = rt->rt6i_table->tb6_id; +else + rtm->rtm_table =RT6_TABLE_UNSPEC ; rtm->rtm_table =RT_TABLE_MAIN ;
This looks like a mistake, the table ID is overwritten again.
net/ipv6/route.c +0 -1
@@ -1898,7 +1898,6 @@ static int rt6_fill_node(struct sk_buff rtm->rtm_table = rt->rt6i_table->tb6_id; else rtm->rtm_table = RT6_TABLE_UNSPEC; - rtm->rtm_table =RT_TABLE_MAIN ;if (rt->rt6i_flags&RTF_REJECT ) rtm->rtm_type =RTN_UNREACHABLE ;else if (rt->rt6i_dev && (rt->rt6i_dev->flags&IFF_LOOPBACK ))
David Miller
maintainerRe: [PATCH 2/5] [IPV6]: Multiple Routing Tables
From: Patrick McHardy <[email protected]>
Date: Sat, 05 Aug 2006 11:00:36 +0200
Quoted 11 lines
Review
Quoted 5 lines · Thomas Graf
(quoted diff) +4
-0+ if (rt->rt6i_table) + rtm->rtm_table = rt->rt6i_table->tb6_id; + else + rtm->rtm_table = RT6_TABLE_UNSPEC; rtm->rtm_table = RT_TABLE_MAIN;This looks like a mistake, the table ID is overwritten again.
Signed-off-by Patrick McHardy <[email protected]>
Good catch Patrick, patch applied.
Thanks a lot.
PATCH 3/5 : Protocol Independant Policy Routing Rules Framework
In reply to Thomas GrafDerived from net/ipv/fib_rules.c
include/linux/fib_rules.h new file +60 -0
@@ -0,0 +1,60 @@ +#ifndef __LINUX_FIB_RULES_H +#define __LINUX_FIB_RULES_H + +#include <linux/types.h> +#include <linux/rtnetlink.h> + +/* rule is permanent, and cannot be deleted */ +#define FIB_RULE_PERMANENT 1 + +struct fib_rule_hdr +{ +__u8 family; +__u8 dst_len; +__u8 src_len; +__u8 tos; + +__u8 table; +__u8 res1;/* reserved */ +__u8 res2;/* reserved */ +__u8 action; + +__u32 flags; +}; + +enum +{ +FRA_UNSPEC , +FRA_DST ,/* destination address */ +FRA_SRC ,/* source address */ +FRA_IFNAME ,/* interface name */ +FRA_UNUSED1 , +FRA_UNUSED2 , +FRA_PRIORITY ,/* priority/preference */ +FRA_UNUSED3 , +FRA_UNUSED4 , +FRA_UNUSED5 , +FRA_FWMARK ,/* netfilter mark (IPv4) */ +FRA_FLOW ,/* flow/class id */ + __FRA_MAX +}; + +#define FRA_MAX (__FRA_MAX - 1) + +enum +{ +FR_ACT_UNSPEC , +FR_ACT_TO_TBL ,/* Pass to fixed table */ +FR_ACT_RES1 , +FR_ACT_RES2 , +FR_ACT_RES3 , +FR_ACT_RES4 , +FR_ACT_BLACKHOLE ,/* Drop without notification */ +FR_ACT_UNREACHABLE ,/* Drop with ENETUNREACH */ +FR_ACT_PROHIBIT ,/* Drop with EACCES */ + __FR_ACT_MAX, +}; + +#define FR_ACT_MAX (__FR_ACT_MAX - 1) + +#endif
include/net/fib_rules.h new file +90 -0
90 lines not on this page · raw message
net/Kconfig +3 -0
@@ -251,6 +251,9 @@ config WIRELESS_EXT source "net/netlabel/Kconfig" +config FIB_RULES + bool + endif # if NET endmenu # Networking
net/core/Makefile +1 -0
@@ -17,3 +17,4 @@ obj-$(CONFIG_NET_PKTGEN) += pktgen.o obj-$(CONFIG_WIRELESS_EXT) += wireless.o obj-$(CONFIG_NETPOLL) += netpoll.o obj-$(CONFIG_NET_DMA) += user_dma.o +obj-$(CONFIG_FIB_RULES) += fib_rules.o
net/core/fib_rules.c new file +416 -0
416 lines not on this page · raw message
net/core/rtnetlink.c +7 -2
@@ -49,6 +49,7 @@#include <net/udp.h> #include <net/sock.h> #include <net/pkt_sched.h> +#include <net/fib_rules.h> #include <net/netlink.h> #ifdef CONFIG_NET_WIRELESS_RTNETLINK #include <linux/wireless.h>
@@ -103,7 +104,7 @@ static const int rtm_min[RTM_NR_FAMILIES [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_NEWRULE)] = NLMSG_LENGTH(sizeof(struct fib_rule_hdr)), [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)),
@@ -120,7 +121,7 @@ static const int rta_max[RTM_NR_FAMILIES [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_NEWRULE)] = FRA_MAX, [RTM_FAM(RTM_NEWQDISC)] = TCA_MAX, [RTM_FAM(RTM_NEWTCLASS)] = TCA_MAX, [RTM_FAM(RTM_NEWTFILTER)] = TCA_MAX,
@@ -744,6 +745,10 @@ static struct rtnetlink_link link_rtnetl [RTM_NEWNEIGH - RTM_BASE] = { .doit = neigh_add }, [RTM_DELNEIGH - RTM_BASE] = { .doit = neigh_delete }, [RTM_GETNEIGH - RTM_BASE] = { .dumpit = neigh_dump_info }, +#ifdef CONFIG_FIB_RULES + [RTM_NEWRULE - RTM_BASE] = { .doit = fib_nl_newrule }, + [RTM_DELRULE - RTM_BASE] = { .doit = fib_nl_delrule }, +#endif [RTM_GETRULE - RTM_BASE] = { .dumpit = rtnetlink_dump_all }, [RTM_GETNEIGHTBL - RTM_BASE] = { .dumpit = neightbl_dump_info }, [RTM_SETNEIGHTBL - RTM_BASE] = { .doit = neightbl_set },
PATCH 4/5 : Policy Routing Rules
In reply to Thomas GrafAdds support for policy routing rules including a new local table for routes with a local destination.
net/ipv6/fib6_rules.c new file +251 -0
@@ -0,0 +1,251 @@ +/* +* net/ipv6/fib6_rules.c IPv6 Routing Policy Rules +* +* Copyright (C)2003-2006 Helsinki University of Technology +* Copyright (C)2003-2006 USAGI/WIDE Project +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License as +* published by the Free Software Foundation, version 2. +* +* Authors +* Thomas Graf <[email protected]> +* Ville Nuorvala <[email protected]> +*/ + +#include <linux/config.h> +#include <linux/netdevice.h> + +#include <net/fib_rules.h> +#include <net/ipv6.h> +#include <net/ip6_route.h> +#include <net/netlink.h> + +struct fib6_rule +{ +struct fib_rule common; +struct rt6key src; +struct rt6key dst; +u8 tclass; +}; + +static struct fib_rules_ops fib6_rules_ops; + +static struct fib6_rule main_rule = { + .common = { + .refcnt =ATOMIC_INIT (2 ), + .pref =0x7FFE , + .action =FR_ACT_TO_TBL , + .table =RT6_TABLE_MAIN , + }, +}; + +static struct fib6_rule local_rule = { + .common = { + .refcnt =ATOMIC_INIT (2 ), + .pref =0 , + .action =FR_ACT_TO_TBL , + .table =RT6_TABLE_LOCAL , + .flags =FIB_RULE_PERMANENT , + }, +}; + +static LIST_HEAD (fib6_rules); + +struct dst_entry *fib6_rule_lookup (struct flowi *fl,int flags, +pol_lookup_t lookup) +{ +struct fib_lookup_arg arg = { + .lookup_ptr = lookup, + }; + +fib_rules_lookup (&fib6_rules_ops, fl, flags, &arg); +if (arg.rule) +fib_rule_put (arg.rule); + +return (struct dst_entry *) arg.result; +} + +int fib6_rule_action (struct fib_rule *rule,struct flowi *flp, +int flags,struct fib_lookup_arg *arg) +{ +struct rt6_info *rt =NULL ; +struct fib6_table *table; +pol_lookup_t lookup = arg->lookup_ptr; + +switch (rule->action) { +case FR_ACT_TO_TBL : +break ; +case FR_ACT_UNREACHABLE : + rt = &ip6_null_entry; + goto discard_pkt; +default : +case FR_ACT_BLACKHOLE : + rt = &ip6_blk_hole_entry; + goto discard_pkt; +case FR_ACT_PROHIBIT : + rt = &ip6_prohibit_entry; + goto discard_pkt; + } + + table =fib6_get_table (rule->table); +if (table) + rt =lookup (table, flp, flags); + +if (rt != &ip6_null_entry) + goto out; + +dst_release (&rt->u.dst); +discard_pkt: +dst_hold (&rt->u.dst); +out: + arg->result = rt; +return rt ==NULL ? -EAGAIN :0 ; +} + + +static int fib6_rule_match (struct fib_rule *rule,struct flowi *fl,int flags) +{ +struct fib6_rule *r = (struct fib6_rule *) rule; + +if (!ipv6_prefix_equal (&fl->fl6_dst, &r->dst.addr, r->dst.plen)) +return 0 ; + +if ((flags &RT6_F_HAS_SADDR ) && + !ipv6_prefix_equal (&fl->fl6_src, &r->src.addr, r->src.plen)) +return 0 ; + +return 1 ; +} + +static struct nla_policy fib6_rule_policy[RTA_MAX +1 ]__read_mostly = { + [FRA_IFNAME ] = { .type =NLA_STRING }, + [FRA_PRIORITY ] = { .type =NLA_U32 }, + [FRA_SRC ] = { .minlen =sizeof (struct in6_addr ) }, + [FRA_DST ] = { .minlen =sizeof (struct in6_addr ) }, +}; + +static int fib6_rule_configure (struct fib_rule *rule,struct sk_buff *skb, +struct nlmsghdr *nlh,struct fib_rule_hdr *frh, +struct nlattr **tb) +{ +int err = -EINVAL ; +struct fib6_rule *rule6 = (struct fib6_rule *) rule; + +if (frh->src_len >128 || frh->dst_len >128 || + (frh->tos & ~IPV6_FLOWINFO_MASK )) + goto errout; + +if (rule->action ==FR_ACT_TO_TBL ) { +if (rule->table ==RT6_TABLE_UNSPEC ) + goto errout; + +if (fib6_new_table (rule->table) ==NULL ) { + err = -ENOBUFS ; + goto errout; + } + } + +if (tb[FRA_SRC ]) +nla_memcpy (&rule6->src.addr, tb[FRA_SRC ], +sizeof (struct in6_addr )); + +if (tb[FRA_DST ]) +nla_memcpy (&rule6->dst.addr, tb[FRA_DST ], +sizeof (struct in6_addr )); + + rule6->src.plen = frh->src_len; + rule6->dst.plen = frh->dst_len; + rule6->tclass = frh->tos; + + err =0 ; +errout: +return err; +} + +static int fib6_rule_compare (struct fib_rule *rule,struct fib_rule_hdr *frh, +struct nlattr **tb) +{ +struct fib6_rule *rule6 = (struct fib6_rule *) rule; + +if (frh->src_len && (rule6->src.plen != frh->src_len)) +return 0 ; + +if (frh->dst_len && (rule6->dst.plen != frh->dst_len)) +return 0 ; + +if (frh->tos && (rule6->tclass != frh->tos)) +return 0 ; + +if (tb[FRA_SRC ] && +nla_memcmp (tb[FRA_SRC ], &rule6->src.addr,sizeof (struct in6_addr ))) +return 0 ; + +if (tb[FRA_DST ] && +nla_memcmp (tb[FRA_DST ], &rule6->dst.addr,sizeof (struct in6_addr ))) +return 0 ; + +return 1 ; +} + +static int fib6_rule_fill (struct fib_rule *rule,struct sk_buff *skb, +struct nlmsghdr *nlh,struct fib_rule_hdr *frh) +{ +struct fib6_rule *rule6 = (struct fib6_rule *) rule; + + frh->family =AF_INET6 ; + frh->dst_len = rule6->dst.plen; + frh->src_len = rule6->src.plen; + frh->tos = rule6->tclass; + +if (rule6->dst.plen) +NLA_PUT (skb,FRA_DST ,sizeof (struct in6_addr ), + &rule6->dst.addr); + +if (rule6->src.plen) +NLA_PUT (skb,FRA_SRC ,sizeof (struct in6_addr ), + &rule6->src.addr); + +return 0 ; + +nla_put_failure: +return -ENOBUFS ; +} + +int fib6_rules_dump (struct sk_buff *skb,struct netlink_callback *cb) +{ +return fib_rules_dump (skb, cb,AF_INET6 ); +} + +static u32 fib6_rule_default_pref (void ) +{ +return 0x3FFF ; +} + +static struct fib_rules_ops fib6_rules_ops = { + .family =AF_INET6 , + .rule_size =sizeof (struct fib6_rule ), + .action = fib6_rule_action, + .match = fib6_rule_match, + .configure = fib6_rule_configure, + .compare = fib6_rule_compare, + .fill = fib6_rule_fill, + .default_pref = fib6_rule_default_pref, + .nlgroup =RTNLGRP_IPV6_RULE , + .policy = fib6_rule_policy, + .rules_list = &fib6_rules, + .owner =THIS_MODULE , +}; + +void __init fib6_rules_init (void ) +{ +list_add_tail (&local_rule.common.list, &fib6_rules); +list_add_tail (&main_rule.common.list, &fib6_rules); + +fib_rules_register (&fib6_rules_ops); +} + +void fib6_rules_cleanup (void ) +{ +fib_rules_unregister (&fib6_rules_ops); +}
net/ipv6/Kconfig +1 -0
@@ -138,6 +138,7 @@ config IPV6_TUNNEL config IPV6_MULTIPLE_TABLES bool "IPv6: Multiple Routing Tables" depends on IPV6 && EXPERIMENTAL + select FIB_RULES ---help--- Support multiple routing tables.
net/ipv6/Makefile +1 -0
@@ -13,6 +13,7 @@ ipv6-objs := af_inet6.o anycast.o ip6_ou ipv6-$(CONFIG_XFRM) += xfrm6_policy.o xfrm6_state.o xfrm6_input.o \ xfrm6_output.o ipv6-$(CONFIG_NETFILTER) += netfilter.o +ipv6-$(CONFIG_IPV6_MULTIPLE_TABLES) += fib6_rules.o ipv6-objs += $(ipv6-y) obj-$(CONFIG_INET6_AH) += ah6.o
include/net/ip6_fib.h +8 -1
@@ -155,7 +155,6 @@ struct fib6_table {#define RT6_TABLE_UNSPEC RT_TABLE_UNSPEC#define RT6_TABLE_MAIN RT_TABLE_MAIN -#define RT6_TABLE_LOCAL RT6_TABLE_MAIN#define RT6_TABLE_DFLT RT6_TABLE_MAIN#define RT6_TABLE_INFO RT6_TABLE_MAIN#define RT6_TABLE_PREFIX RT6_TABLE_MAIN
@@ -163,9 +162,11 @@ struct fib6_table {#ifdef CONFIG_IPV6_MULTIPLE_TABLES #define FIB6_TABLE_MIN 1#define FIB6_TABLE_MAX RT_TABLE_MAX +#define RT6_TABLE_LOCAL RT_TABLE_LOCAL#else #define FIB6_TABLE_MIN RT_TABLE_MAIN#define FIB6_TABLE_MAX FIB6_TABLE_MIN +#define RT6_TABLE_LOCAL RT6_TABLE_MAIN#endif #define RT6_F_STRICT 1
@@ -221,5 +222,11 @@ extern void fib6_run_gc(unsigned longextern void fib6_gc_cleanup (void );extern void fib6_init (void ); + +extern void fib6_rules_init (void ); +extern void fib6_rules_cleanup (void ); +extern int fib6_rules_dump (struct sk_buff *, +struct netlink_callback *); +#endif #endif
net/ipv6/route.c +50 -0
66 lines not on this page · raw message
net/ipv6/ip6_fib.c +10 -11
@@ -159,6 +159,15 @@ static struct fib6_table fib6_main_tbl =#ifdef CONFIG_IPV6_MULTIPLE_TABLES +static struct fib6_table fib6_local_tbl = { + .tb6_id =RT6_TABLE_LOCAL , + .tb6_lock =RW_LOCK_UNLOCKED , + .tb6_root = { + .leaf = &ip6_null_entry, + .fn_flags =RTN_ROOT |RTN_TL_ROOT |RTN_RTINFO , + }, +}; +#define FIB_TABLE_HASHSZ 256static struct hlist_head fib_table_hash[FIB_TABLE_HASHSZ ];
@@ -228,20 +237,10 @@ struct fib6_table *fib6_get_table(u32 id return NULL; } -struct dst_entry *fib6_rule_lookup (struct flowi *fl,int flags, -pol_lookup_t lookup) -{ -/* -* TODO: Add rule lookup -*/ -struct fib6_table *table =fib6_get_table (RT6_TABLE_MAIN ); - -return (struct dst_entry *)lookup (table, fl, flags); -} -static void __init fib6_tables_init (void ) {fib6_link_table (&fib6_main_tbl); +fib6_link_table (&fib6_local_tbl); }#else
include/net/ip6_route.h +5 -0
@@ -41,6 +41,11 @@ struct pol_chain {extern struct rt6_info ip6_null_entry; +#ifdef CONFIG_IPV6_MULTIPLE_TABLES +extern struct rt6_info ip6_prohibit_entry; +extern struct rt6_info ip6_blk_hole_entry; +#endif +extern int ip6_rt_gc_interval;extern void ip6_route_input (struct sk_buff *skb);
net/ipv6/addrconf.c +1 -0
@@ -3370,6 +3370,7 @@ static struct rtnetlink_link inet6_rtnet [RTM_DELROUTE - RTM_BASE] = { .doit = inet6_rtm_delroute, }, [RTM_GETROUTE -RTM_BASE ] = { .doit = inet6_rtm_getroute, .dumpit = inet6_dump_fib, }, + [RTM_GETRULE - RTM_BASE] = { .dumpit = fib6_rules_dump, }, };static void __ipv6_ifa_notify (int event,struct inet6_ifaddr *ifp)
include/linux/rtnetlink.h +2 -0
@@ -889,6 +889,8 @@ enum rtnetlink_groups { RTNLGRP_NOP4, RTNLGRP_IPV6_PREFIX,#define RTNLGRP_IPV6_PREFIX RTNLGRP_IPV6_PREFIX + RTNLGRP_IPV6_RULE, +#define RTNLGRP_IPV6_RULE RTNLGRP_IPV6_RULE __RTNLGRP_MAX };#define RTNLGRP_MAX (__RTNLGRP_MAX - 1)
PATCH 5/5 : Use Protocol Independant Policy Routing Rules Framework
In reply to Thomas Grafinclude/net/ip_fib.h +7 -7
@@ -18,6 +18,7 @@#include <net/flow.h> #include <linux/seq_file.h> +#include <net/fib_rules.h> /* WARNING: The ordering of these elements must match ordering * of RTA_* rtnetlink attribute numbers.
@@ -203,9 +204,8 @@ static inline void fib_select_default(co#define ip_fib_main_table (fib_tables[RT_TABLE_MAIN])extern struct fib_table * fib_tables[RT_TABLE_MAX +1 ]; -extern int fib_lookup (const struct flowi *flp,struct fib_result *res); +extern int fib_lookup (struct flowi *flp,struct fib_result *res);extern struct fib_table *__fib_new_table (int id); -extern void fib_rule_put (struct fib_rule *r);static inline struct fib_table *fib_get_table (int id) {
@@ -251,15 +251,15 @@ extern u32 __fib_res_prefsrc(struct fibextern struct fib_table *fib_hash_init (int id);#ifdef CONFIG_IP_MULTIPLE_TABLES -/* Exported by fib_rules.c */ +extern int fib4_rules_dump (struct sk_buff *skb,struct netlink_callback *cb); + +extern void __init fib4_rules_init (void ); +extern void __exit fib4_rules_cleanup(void); -extern int inet_rtm_delrule (struct sk_buff *skb,struct nlmsghdr * nlh,void *arg); -extern int inet_rtm_newrule (struct sk_buff *skb,struct nlmsghdr * nlh,void *arg); -extern int inet_dump_rules (struct sk_buff *skb,struct netlink_callback *cb);#ifdef CONFIG_NET_CLS_ROUTE extern u32 fib_rules_tclass (struct fib_result *res);#endif -extern void fib_rules_init (void ); +#endif static inline void fib_combine_itag (u32 *itag,struct fib_result *res)
net/ipv4/Kconfig +1 -0
@@ -88,6 +88,7 @@ config IP_FIB_HASH config IP_MULTIPLE_TABLES bool "IP: policy routing" depends on IP_ADVANCED_ROUTER + select FIB_RULES ---help--- Normally, a router decides what to do with a received packet based solely on the packet's final destination address. If you say Y here,
net/ipv4/devinet.c +1 -3
@@ -1151,9 +1151,7 @@ static struct rtnetlink_link inet_rtnetl [RTM_GETROUTE -RTM_BASE ] = { .doit = inet_rtm_getroute, .dumpit = inet_dump_fib, }, #ifdef CONFIG_IP_MULTIPLE_TABLES - [RTM_NEWRULE - RTM_BASE] = { .doit = inet_rtm_newrule, }, - [RTM_DELRULE - RTM_BASE] = { .doit = inet_rtm_delrule, }, - [RTM_GETRULE - RTM_BASE] = { .dumpit = inet_dump_rules, }, + [RTM_GETRULE - RTM_BASE] = { .dumpit = fib4_rules_dump, }, #endif };
net/ipv4/fib_rules.c +243 -370
710 lines not on this page · raw message
net/ipv4/fib_frontend.c +1 -1
@@ -656,7 +656,7 @@ void __init ip_fib_init(void) ip_fib_local_table =fib_hash_init (RT_TABLE_LOCAL ); ip_fib_main_table =fib_hash_init (RT_TABLE_MAIN );#else -fib_rules_init (); +fib4_rules_init ();#endif register_netdevice_notifier (&fib_netdev_notifier);
David Miller
maintainerFrom: Thomas Graf <[email protected]>
Date: Fri, 04 Aug 2006 12:23:08 +0200
Quoted 6 lines
This patchset implements multiple IPv6 routing tables and policy routing. Even though the code is almost rewritten entirely the work is based on the MIPL patch found on mobile-ipv6.org which is being jointly developed by Helsinki University of Technology (HUT) and the USAGI/WIDE Project.
Quoted 8 lines
Reference counting on routing tables was removed to decrease the number of required atomic operations during route lookup.
The tables are now organized in a hashtable to prepare for the change in supporting more than 255 tables.
Matching sources address in policy rules is no longer dependant on
CONFIG_SUBTREES.
All patches added to net-2.6.19, thanks a lot Thomas.
Please submit any further improvements and bug fixes relative to these changes, thanks a lot.
In article <[email protected]> (at Fri, 04 Aug 2006 12:23:08 +0200), Thomas Graf <[email protected]> says:
Quoted 2 lines
This patchset implements multiple IPv6 routing tables and policy routing. Even though the code is almost rewritten
:
Thomas, there are some coflicts with current net-2.6 tree. Would you please sync with latest net-2.6 tree. Thank you.
--yoshfuji
* YOSHIFUJI Hideaki / ?$B5HF#1QL@ <[email protected]> 2006-08-05 00:58
Quoted 8 lines
In article <[email protected]> (at Fri, 04 Aug 2006 12:23:08 +0200), Thomas Graf <[email protected]> says:
Quoted 2 lines
This patchset implements multiple IPv6 routing tables and policy routing. Even though the code is almost rewritten
:
Thomas, there are some coflicts with current net-2.6 tree. Would you please sync with latest net-2.6 tree.
The patches are against the net-2.6.19 tree.
In article <[email protected]> (at Fri, 4 Aug 2006 19:41:20 +0200), Thomas Graf <[email protected]> says:
Quoted 1 line
The patches are against the net-2.6.19 tree.
Oh.... sorry, you're absolutely right...
--yoshfuji