Updating the dead-gateway detection patch...
Subsystems (5)
I've revised this patch for 2.6.26.8. Can someone please check it for correctness? (I have no easy way to test it.)
Thanks.
-Philip
include/linux/rtnetlink.h renamed from linux/include/linux/rtnetlink.h +2 -0
@@ -303,6 +303,8 @@ struct rtnexthop#define RTNH_F_DEAD 1/* Nexthop is dead (used by multipath) */ #define RTNH_F_PERVASIVE 2/* Do recursive gateway lookup */ #define RTNH_F_ONLINK 4/* Gateway is forced on link */ +#define RTNH_F_SUSPECT 8/* We don't know the real state */ +#define RTNH_F_BADSTATE (RTNH_F_DEAD | RTNH_F_SUSPECT)/* Macros to handle hexthops */
include/net/flow.h renamed from linux/include/net/flow.h +4 -0
@@ -19,6 +19,8 @@ struct flowi {struct {__be32 daddr;__be32 saddr; +__be32 lsrc; +__be32 gw;__u8 tos;__u8 scope; } ip4_u;
@@ -43,6 +45,8 @@ struct flowi {#define fl6_flowlabel nl_u.ip6_u.flowlabel#define fl4_dst nl_u.ip4_u.daddr#define fl4_src nl_u.ip4_u.saddr +#define fl4_lsrc nl_u.ip4_u.lsrc +#define fl4_gw nl_u.ip4_u.gw#define fl4_tos nl_u.ip4_u.tos#define fl4_scope nl_u.ip4_u.scope
include/net/ip_fib.h renamed from linux/include/net/ip_fib.h +4 -0
@@ -207,6 +207,8 @@ extern int fib_lookup(struct net *n, strextern struct fib_table *fib_new_table (struct net *net,u32 id);extern struct fib_table *fib_get_table (struct net *net,u32 id); +extern int fib_result_table (struct fib_result *res); +#endif /* CONFIG_IP_MULTIPLE_TABLES */ /* Exported by fib_frontend.c */
@@ -276,4 +278,6 @@ static inline void fib_proc_exit(struct }#endif +extern rwlock_t fib_nhflags_lock; +#endif /* _NET_FIB_H */
include/net/netfilter/nf_nat.h renamed from linux/include/net/netfilter/nf_nat.h +7 -0
@@ -77,6 +77,13 @@ struct nf_conn_nat#endif }; +/* Call input routing for SNAT-ed traffic */ +extern unsigned int ip_nat_route_input (unsigned int hooknum, +struct sk_buff *skb, +const struct net_device *in, +const struct net_device *out, +int (*okfn)(struct sk_buff *)); +/* Set up the info structure to map into this range. */ extern unsigned int nf_nat_setup_info(struct nf_conn *ct, const struct nf_nat_range *range,
include/net/route.h renamed from linux/include/net/route.h +1 -0
@@ -116,6 +116,7 @@extern int ip_route_output_key (struct net *,struct rtable **,struct flowi *flp);extern int ip_route_output_flow (struct net *,struct rtable **rp,struct flowi *flp,struct sock *sk,int flags);extern int ip_route_input (struct sk_buff *,__be32 dst,__be32 src,u8 tos,struct net_device *devin); +extern int ip_route_input_lookup (struct sk_buff *,__be32 dst,__be32 src,u8 tos,struct net_device *devin,__be32 lsrc);extern unsigned short ip_rt_frag_needed (struct net *net,struct iphdr *iph,unsigned short new_mtu,struct net_device *dev);extern void ip_rt_send_redirect (struct sk_buff *skb);
net/bridge/br_netfilter.c renamed from linux/net/bridge/br_netfilter.c +4 -0
@@ -325,6 +325,10 @@ static int br_nf_pre_routing_finish(strustruct nf_bridge_info *nf_bridge = skb->nf_bridge;int err; +/* Old skb->dst is not expected, it is lost in all cases */ +dst_release (skb->dst); + skb->dst =NULL ; +if (nf_bridge->mask &BRNF_PKT_TYPE ) { skb->pkt_type =PACKET_OTHERHOST ; nf_bridge->mask ^=BRNF_PKT_TYPE ;
net/ipv4/fib_frontend.c renamed from linux/net/ipv4/fib_frontend.c +2 -0
@@ -49,6 +49,8 @@#ifndef CONFIG_IP_MULTIPLE_TABLES +#define FIB_RES_TABLE (r) (RT_TABLE_MAIN) +static int __net_init fib4_rules_init (struct net *net) {
struct fib_table *local_table, *main_table;
@@ -73,6 +75,8 @@ fail:
}
#else
+#define FIB_RES_TABLE(r) (fib_result_table(r))
+
struct fib_table *fib_new_table(struct net *net, u32 id) {
struct fib_table *tb;
@@ -127,7 +131,8 @@ void fib_select_default(struct net *net,
table = res->r->table;
#endif
tb = fib_get_table(net, table);
- if (FIB_RES_GW(*res) && FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK)
+ if ((FIB_RES_GW(*res) && FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK) ||
+ FIB_RES_NH(*res).nh_scope == RT_SCOPE_HOST)
tb->tb_select_default(tb, flp, res);
}
@@ -241,6 +246,9 @@ int fib_validate_source(__be32 src, __be
.tos = tos } },
.iif = oif };
struct fib_result res;
+ int table;
+ unsigned char prefixlen;
+ unsigned char scope;
int no_addr, rpf;
int ret;
struct net *net;
@@ -264,31 +272,35 @@ int fib_validate_source(__be32 src, __be
goto e_inval_res;
*spec_dst = FIB_RES_PREFSRC(res); fib_combine_itag(itag, &res);
-#ifdef CONFIG_IP_ROUTE_MULTIPATH
- if (FIB_RES_DEV(res) == dev || res.fi->fib_nhs > 1)
-#else
if (FIB_RES_DEV(res) == dev)
-#endif
{
ret = FIB_RES_NH(res).nh_scope >= RT_SCOPE_HOST; fib_res_put(&res);
return ret;
}
+ table = FIB_RES_TABLE(&res);
+ prefixlen = res.prefixlen;
+ scope = res.scope;
fib_res_put(&res);
if (no_addr)
goto last_resort;
- if (rpf)
- goto e_inval;
fl.oif = dev->ifindex;
ret = 0;
if (fib_lookup(net, &fl, &res) == 0) {
- if (res.type == RTN_UNICAST) {
+ if (res.type == RTN_UNICAST &&
+ ((table == FIB_RES_TABLE(&res) &&
+ res.prefixlen >= prefixlen && res.scope >= scope) ||
+ !rpf)) {
*spec_dst = FIB_RES_PREFSRC(res); ret = FIB_RES_NH(res).nh_scope >= RT_SCOPE_HOST;
+ fib_res_put(&res);
+ return ret;
}
fib_res_put(&res);
}
+ if (rpf)
+ goto e_inval;
return ret;
last_resort:
@@ -911,9 +923,7 @@ static int fib_inetaddr_event(struct not
switch (event) {
case NETDEV_UP:
fib_add_ifaddr(ifa);
-#ifdef CONFIG_IP_ROUTE_MULTIPATH
fib_sync_up(ifa->ifa_dev->dev);
-#endif
rt_cache_flush(-1);
break;
case NETDEV_DOWN:
@@ -949,9 +959,7 @@ static int fib_netdev_event(struct notif
for_ifa(in_dev) {
fib_add_ifaddr(ifa);
} endfor_ifa(in_dev);
-#ifdef CONFIG_IP_ROUTE_MULTIPATH
fib_sync_up(dev);
-#endif
rt_cache_flush(-1);
break;
case NETDEV_DOWN:
net/ipv4/fib_hash.c renamed from linux/net/ipv4/fib_hash.c +43 -17
122 lines not on this page · raw message
net/ipv4/fib_lookup.h renamed from linux/net/ipv4/fib_lookup.h +3 -1
@@ -8,6 +8,7 @@struct fib_alias {struct list_head fa_list;struct fib_info *fa_info; +int fa_last_dflt;u8 fa_tos;u8 fa_type;u8 fa_scope;
@@ -38,7 +39,8 @@ extern struct fib_alias *fib_find_alias( u8 tos, u32 prio);extern int fib_detect_death (struct fib_info *fi,int order,struct fib_info **last_resort, -int *last_idx,int dflt); +int *last_idx,int *dflt,int *last_nhsel, +const struct flowi *flp);static inline void fib_result_assign (struct fib_result *res,struct fib_info *fi)
net/ipv4/fib_rules.c renamed from linux/net/ipv4/fib_rules.c +5 -0
@@ -54,6 +54,11 @@ u32 fib_rules_tclass(struct fib_result * }#endif +int fib_result_table (struct fib_result *res) +{ +return res->r->table; +} +int fib_lookup (struct net *net,struct flowi *flp,struct fib_result *res) {struct fib_lookup_arg arg = {
net/ipv4/fib_semantics.c renamed from linux/net/ipv4/fib_semantics.c +226 -67
436 lines not on this page · raw message
net/ipv4/netfilter/ipt_MASQUERADE.c renamed from linux/net/ipv4/netfilter/ipt_MASQUERADE.c +25 -6
@@ -59,7 +59,7 @@ masquerade_tg(struct sk_buff *skb, constenum ip_conntrack_info ctinfo;struct nf_nat_range newrange;const struct nf_nat_multi_range_compat *mr; -const struct rtable *rt; +struct rtable *rt;__be32 newsrc;NF_CT_ASSERT (hooknum ==NF_INET_POST_ROUTING );
@@ -77,13 +77,32 @@ masquerade_tg(struct sk_buff *skb, constreturn NF_ACCEPT ; mr = targinfo; - rt = skb->rtable; - newsrc =inet_select_addr (out, rt->rt_gateway,RT_SCOPE_UNIVERSE ); -if (!newsrc) { -printk ("MASQUERADE: %s ate my IP address\n" , out->name); -return NF_DROP ; + + { +struct flowi fl = { .nl_u = { .ip4_u = + { .daddr =ip_hdr (skb)->daddr, + .tos = (RT_TOS (ip_hdr (skb)->tos) | +RTO_CONN ), + .gw = ((struct rtable *) skb->dst)->rt_gateway, + } }, + .mark = skb->mark, + .oif = out->ifindex }; +#ifdef CONFIG_NET_NS +if (ip_route_output_key (out->nd_net, &rt, &fl) !=0 ) { +#else +if (ip_route_output_key (&init_net, &rt, &fl) !=0 ) { +#endif +/* Funky routing can do this. */ +if (net_ratelimit ()) +printk ("MASQUERADE:" +" No route: Rusty's brain broke!\n" ); +return NF_DROP ; + } } + newsrc = rt->rt_src; +ip_rt_put (rt); +write_lock_bh (&masq_lock); nat->masq_index = out->ifindex;write_unlock_bh (&masq_lock);
net/ipv4/netfilter/nf_nat_core.c renamed from linux/net/ipv4/netfilter/nf_nat_core.c +46 -0
52 lines not on this page · raw message
net/ipv4/netfilter/nf_nat_standalone.c renamed from linux/net/ipv4/netfilter/nf_nat_standalone.c +8 -0
@@ -282,6 +282,14 @@ static struct nf_hook_ops nf_nat_ops[] _ .hooknum = NF_INET_PRE_ROUTING, .priority = NF_IP_PRI_NAT_DST, }, +/* Before routing, route before mangling */ + { + .hook = ip_nat_route_input, + .owner = THIS_MODULE, + .pf = PF_INET, + .hooknum = NF_INET_PRE_ROUTING, + .priority = NF_IP_PRI_LAST-1, + },/* After packet filtering, change source */ { .hook = nf_nat_out,
net/ipv4/route.c renamed from linux/net/ipv4/route.c +55 -16
242 lines not on this page · raw message