Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 20698
Collapse All | Expand All

(-)linux-2.4.21/Documentation/filesystems/proc.txt (+32 lines)
Lines 1551-1556 the net, it will prevent spoofing a Link Here
1551
(external addresses  can  still  be  spoofed), without the need for additional
1551
(external addresses  can  still  be  spoofed), without the need for additional
1552
firewall rules.
1552
firewall rules.
1553
1553
1554
forward_shared
1555
--------------
1556
1557
Integer value determines if a source validation should allow forwarding
1558
of packets with local source address. 1 means yes, 0 means no. By default
1559
the flag is disabled and such packets are not forwarded.
1560
1561
If you enable this flag on internal network, the router will forward
1562
packets from internal hosts with shared IP addresses no matter how
1563
the rp_filter is set. This flag is activated only if it is enabled
1564
both in specific device section and in "all" section.
1565
1566
rp_filter_mask
1567
--------------
1568
1569
Integer value representing bitmask of the mediums for which the reverse path
1570
protection is disabled. If the source validation results in reverse path
1571
to interface with medium_id value in the 1..31 range the access is
1572
allowed if the corresponding bit is set in the bitmask. The bitmask value
1573
is considered only when rp_filter is enabled. By default the bitmask is
1574
empty preserving the original rp_filter semantic.
1575
1554
secure_redirects
1576
secure_redirects
1555
----------------
1577
----------------
1556
1578
Lines 1568-1573 send_redirects Link Here
1568
1590
1569
Determines whether to send ICMP redirects to other hosts.
1591
Determines whether to send ICMP redirects to other hosts.
1570
1592
1593
hidden
1594
------
1595
1596
Hide addresses attached to this device from other devices.
1597
Such addresses will never be selected by source address autoselection
1598
mechanism, host does not answer broadcast ARP requests for them,
1599
does not announce them as source address of ARP requests, but they
1600
are still reachable via IP. This flag is activated only if it is
1601
enabled both in specific device section and in "all" section.
1602
1571
Routing settings
1603
Routing settings
1572
----------------
1604
----------------
1573
1605
(-)linux-2.4.21/Documentation/networking/ip-sysctl.txt (+29 lines)
Lines 385-390 accept_redirects - BOOLEAN Link Here
385
forwarding - BOOLEAN
385
forwarding - BOOLEAN
386
	Enable IP forwarding on this interface.
386
	Enable IP forwarding on this interface.
387
387
388
forward_shared - BOOLEAN
389
	Integer value determines if a source validation should allow
390
	forwarding of packets with local source address. 1 means yes,
391
	0 means no. By default the flag is disabled and such packets
392
	are not forwarded.
393
 
394
	If you enable this flag on internal network, the router will forward
395
	packets from internal hosts with shared IP addresses no matter how
396
	the rp_filter is set. This flag is activated only if it is
397
	enabled both in specific device section and in "all" section.
398
388
mc_forwarding - BOOLEAN
399
mc_forwarding - BOOLEAN
389
	Do multicast routing. The kernel needs to be compiled with CONFIG_MROUTE
400
	Do multicast routing. The kernel needs to be compiled with CONFIG_MROUTE
390
	and a multicast routing daemon is required.
401
	and a multicast routing daemon is required.
Lines 477-482 arp_filter - BOOLEAN Link Here
477
	particular interfaces. Only for more complex setups like load-
488
	particular interfaces. Only for more complex setups like load-
478
	balancing, does this behaviour cause problems.
489
	balancing, does this behaviour cause problems.
479
490
491
hidden - BOOLEAN
492
	Hide addresses attached to this device from other devices.
493
	Such addresses will never be selected by source address autoselection
494
	mechanism, host does not answer broadcast ARP requests for them,
495
	does not announce them as source address of ARP requests, but they
496
	are still reachable via IP. This flag is activated only if it is
497
	enabled both in specific device section and in "all" section.
498
499
rp_filter_mask - INTEGER
500
501
	Integer value representing bitmask of the mediums for which the
502
	reverse path protection is disabled. If the source validation
503
	results in reverse path to interface with medium_id value in
504
	the 1..31 range the access is allowed if the corresponding bit
505
	is set in the bitmask. The bitmask value is considered only when
506
	rp_filter is enabled. By default the bitmask is empty preserving
507
	the original rp_filter semantic.
508
480
	arp_filter for the interface will be enabled if at least one of
509
	arp_filter for the interface will be enabled if at least one of
481
	conf/{all,interface}/arp_filter is set to TRUE,
510
	conf/{all,interface}/arp_filter is set to TRUE,
482
	it will be disabled otherwise
511
	it will be disabled otherwise
(-)linux-2.4.21/include/linux/inetdevice.h (+7 lines)
Lines 17-24 struct ipv4_devconf Link Here
17
	int	forwarding;
17
	int	forwarding;
18
	int	mc_forwarding;
18
	int	mc_forwarding;
19
	int	tag;
19
	int	tag;
20
	int	hidden;
20
	int     arp_filter;
21
	int     arp_filter;
21
	int	medium_id;
22
	int	medium_id;
23
	int	rp_filter_mask;
24
	int     forward_shared;
22
	void	*sysctl;
25
	void	*sysctl;
23
};
26
};
24
27
Lines 45-55 struct in_device Link Here
45
48
46
#define IN_DEV_LOG_MARTIANS(in_dev)	(ipv4_devconf.log_martians || (in_dev)->cnf.log_martians)
49
#define IN_DEV_LOG_MARTIANS(in_dev)	(ipv4_devconf.log_martians || (in_dev)->cnf.log_martians)
47
#define IN_DEV_PROXY_ARP(in_dev)	(ipv4_devconf.proxy_arp || (in_dev)->cnf.proxy_arp)
50
#define IN_DEV_PROXY_ARP(in_dev)	(ipv4_devconf.proxy_arp || (in_dev)->cnf.proxy_arp)
51
#define IN_DEV_HIDDEN(in_dev)		((in_dev)->cnf.hidden && ipv4_devconf.hidden)
48
#define IN_DEV_SHARED_MEDIA(in_dev)	(ipv4_devconf.shared_media || (in_dev)->cnf.shared_media)
52
#define IN_DEV_SHARED_MEDIA(in_dev)	(ipv4_devconf.shared_media || (in_dev)->cnf.shared_media)
49
#define IN_DEV_TX_REDIRECTS(in_dev)	(ipv4_devconf.send_redirects || (in_dev)->cnf.send_redirects)
53
#define IN_DEV_TX_REDIRECTS(in_dev)	(ipv4_devconf.send_redirects || (in_dev)->cnf.send_redirects)
50
#define IN_DEV_SEC_REDIRECTS(in_dev)	(ipv4_devconf.secure_redirects || (in_dev)->cnf.secure_redirects)
54
#define IN_DEV_SEC_REDIRECTS(in_dev)	(ipv4_devconf.secure_redirects || (in_dev)->cnf.secure_redirects)
51
#define IN_DEV_IDTAG(in_dev)		((in_dev)->cnf.tag)
55
#define IN_DEV_IDTAG(in_dev)		((in_dev)->cnf.tag)
52
#define IN_DEV_MEDIUM_ID(in_dev)	((in_dev)->cnf.medium_id)
56
#define IN_DEV_MEDIUM_ID(in_dev)	((in_dev)->cnf.medium_id)
57
#define IN_DEV_RPFILTER_MASK(in_dev)	((in_dev)->cnf.rp_filter_mask)
53
58
54
#define IN_DEV_RX_REDIRECTS(in_dev) \
59
#define IN_DEV_RX_REDIRECTS(in_dev) \
55
	((IN_DEV_FORWARD(in_dev) && \
60
	((IN_DEV_FORWARD(in_dev) && \
Lines 59-64 struct in_device Link Here
59
64
60
#define IN_DEV_ARPFILTER(in_dev)	(ipv4_devconf.arp_filter || (in_dev)->cnf.arp_filter)
65
#define IN_DEV_ARPFILTER(in_dev)	(ipv4_devconf.arp_filter || (in_dev)->cnf.arp_filter)
61
66
67
#define IN_DEV_FORWARD_SHARED(in_dev)	((in_dev)->cnf.forward_shared && ipv4_devconf.forward_shared)
68
62
struct in_ifaddr
69
struct in_ifaddr
63
{
70
{
64
	struct in_ifaddr	*ifa_next;
71
	struct in_ifaddr	*ifa_next;
(-)linux-2.4.21/include/linux/netfilter_ipv4/ip_nat.h (+8 lines)
Lines 129-133 extern int ip_nat_used_tuple(const struc Link Here
129
extern u_int16_t ip_nat_cheat_check(u_int32_t oldvalinv,
129
extern u_int16_t ip_nat_cheat_check(u_int32_t oldvalinv,
130
				    u_int32_t newval,
130
				    u_int32_t newval,
131
				    u_int16_t oldcheck);
131
				    u_int16_t oldcheck);
132
133
/* Call input routing for SNAT-ed traffic */
134
extern unsigned int ip_nat_route_input(unsigned int hooknum,
135
				       struct sk_buff **pskb,
136
				       const struct net_device *in,
137
				       const struct net_device *out,
138
				       int (*okfn)(struct sk_buff *));
139
132
#endif /*__KERNEL__*/
140
#endif /*__KERNEL__*/
133
#endif
141
#endif
(-)linux-2.4.21/include/linux/rtnetlink.h (-1 / +57 lines)
Lines 46-52 Link Here
46
#define	RTM_DELTFILTER	(RTM_BASE+29)
46
#define	RTM_DELTFILTER	(RTM_BASE+29)
47
#define	RTM_GETTFILTER	(RTM_BASE+30)
47
#define	RTM_GETTFILTER	(RTM_BASE+30)
48
48
49
#define	RTM_MAX		(RTM_BASE+31)
49
#define	RTM_NEWARPRULE	(RTM_BASE+32)
50
#define	RTM_DELARPRULE	(RTM_BASE+33)
51
#define	RTM_GETARPRULE	(RTM_BASE+34)
52
53
#define	RTM_MAX		(RTM_BASE+35)
50
54
51
/* 
55
/* 
52
   Generic structure for encapsulation optional route information.
56
   Generic structure for encapsulation optional route information.
Lines 228-233 struct rtnexthop Link Here
228
#define RTNH_F_DEAD		1	/* Nexthop is dead (used by multipath)	*/
232
#define RTNH_F_DEAD		1	/* Nexthop is dead (used by multipath)	*/
229
#define RTNH_F_PERVASIVE	2	/* Do recursive gateway lookup	*/
233
#define RTNH_F_PERVASIVE	2	/* Do recursive gateway lookup	*/
230
#define RTNH_F_ONLINK		4	/* Gateway is forced on link	*/
234
#define RTNH_F_ONLINK		4	/* Gateway is forced on link	*/
235
#define RTNH_F_SUSPECT		8	/* We don't know the real state	*/
236
#define RTNH_F_BADSTATE		(RTNH_F_DEAD | RTNH_F_SUSPECT)
231
237
232
/* Macros to handle hexthops */
238
/* Macros to handle hexthops */
233
239
Lines 511-516 enum Link Here
511
#define TCA_RTA(r)  ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct tcmsg))))
517
#define TCA_RTA(r)  ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct tcmsg))))
512
#define TCA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct tcmsg))
518
#define TCA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct tcmsg))
513
519
520
/******************************************************************************
521
 *		Definitions used in ARP tables administration
522
 ****/
523
524
#define ARPA_TABLE_INPUT	0
525
#define ARPA_TABLE_OUTPUT	1
526
#define ARPA_TABLE_FORWARD	2
527
#define ARPA_TABLE_ALL		-1
528
529
#define ARPM_F_PREFSRC		0x0001
530
#define ARPM_F_WILDIIF		0x0002
531
#define ARPM_F_WILDOIF		0x0004
532
#define ARPM_F_BROADCAST	0x0008
533
#define ARPM_F_UNICAST		0x0010
534
535
struct arpmsg
536
{
537
	unsigned char		arpm_family;
538
	unsigned char		arpm_table;
539
	unsigned char		arpm_action;
540
	unsigned char		arpm_from_len;
541
	unsigned char		arpm_to_len;
542
	unsigned char		arpm__pad1;
543
	unsigned short		arpm__pad2;
544
	unsigned		arpm_pref;
545
	unsigned		arpm_flags;
546
};
547
548
enum
549
{
550
	ARPA_UNSPEC,
551
	ARPA_FROM,			/* FROM IP prefix	*/
552
	ARPA_TO,			/* TO IP prefix		*/
553
	ARPA_LLFROM,			/* FROM LL prefix	*/
554
	ARPA_LLTO,			/* TO LL prefix		*/
555
	ARPA_LLSRC,			/* New SRC lladdr	*/
556
	ARPA_LLDST,			/* New DST lladdr	*/
557
	ARPA_IIF,			/* In interface prefix	*/
558
	ARPA_OIF,			/* Out interface prefix	*/
559
	ARPA_SRC,			/* New IP SRC		*/
560
	ARPA_DST,			/* New IP DST, not used	*/
561
	ARPA_PACKETS,			/* Packets		*/
562
};
563
564
#define ARPA_MAX	ARPA_PACKETS
565
566
#define ARPA_RTA(r)  ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct arpmsg))))
567
#define ARPA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct arpmsg))
514
568
515
/* SUMMARY: maximal rtattr understood by kernel */
569
/* SUMMARY: maximal rtattr understood by kernel */
516
570
Lines 534-539 enum Link Here
534
#define RTMGRP_DECnet_IFADDR    0x1000
588
#define RTMGRP_DECnet_IFADDR    0x1000
535
#define RTMGRP_DECnet_ROUTE     0x4000
589
#define RTMGRP_DECnet_ROUTE     0x4000
536
590
591
#define RTMGRP_ARP		0x00010000
592
537
/* End of information exported to user level */
593
/* End of information exported to user level */
538
594
539
#ifdef __KERNEL__
595
#ifdef __KERNEL__
(-)linux-2.4.21/include/linux/sysctl.h (+3 lines)
Lines 364-369 enum Link Here
364
	NET_IPV4_CONF_TAG=12,
364
	NET_IPV4_CONF_TAG=12,
365
	NET_IPV4_CONF_ARPFILTER=13,
365
	NET_IPV4_CONF_ARPFILTER=13,
366
	NET_IPV4_CONF_MEDIUM_ID=14,
366
	NET_IPV4_CONF_MEDIUM_ID=14,
367
	NET_IPV4_CONF_HIDDEN=15,
368
	NET_IPV4_CONF_FORWARD_SHARED=16,
369
	NET_IPV4_CONF_RP_FILTER_MASK=17,
367
};
370
};
368
371
369
/* /proc/sys/net/ipv4/netfilter */
372
/* /proc/sys/net/ipv4/netfilter */
(-)linux-2.4.21/include/net/ip_fib.h (-2 / +5 lines)
Lines 162-168 static inline int fib_lookup(const struc Link Here
162
162
163
static inline void fib_select_default(const struct rt_key *key, struct fib_result *res)
163
static inline void fib_select_default(const struct rt_key *key, struct fib_result *res)
164
{
164
{
165
	if (FIB_RES_GW(*res) && FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK)
165
	if ((FIB_RES_GW(*res) && FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK) ||
166
	    FIB_RES_NH(*res).nh_scope == RT_SCOPE_HOST)
166
		main_table->tb_select_default(main_table, key, res);
167
		main_table->tb_select_default(main_table, key, res);
167
}
168
}
168
169
Lines 174-179 extern struct fib_table * fib_tables[RT_ Link Here
174
extern int fib_lookup(const struct rt_key *key, struct fib_result *res);
175
extern int fib_lookup(const struct rt_key *key, struct fib_result *res);
175
extern struct fib_table *__fib_new_table(int id);
176
extern struct fib_table *__fib_new_table(int id);
176
extern void fib_rule_put(struct fib_rule *r);
177
extern void fib_rule_put(struct fib_rule *r);
178
extern __inline__ int fib_result_table(struct fib_result *res);
177
179
178
static inline struct fib_table *fib_get_table(int id)
180
static inline struct fib_table *fib_get_table(int id)
179
{
181
{
Lines 203-209 extern int inet_rtm_newroute(struct sk_b Link Here
203
extern int inet_rtm_getroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg);
205
extern int inet_rtm_getroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg);
204
extern int inet_dump_fib(struct sk_buff *skb, struct netlink_callback *cb);
206
extern int inet_dump_fib(struct sk_buff *skb, struct netlink_callback *cb);
205
extern int fib_validate_source(u32 src, u32 dst, u8 tos, int oif,
207
extern int fib_validate_source(u32 src, u32 dst, u8 tos, int oif,
206
			       struct net_device *dev, u32 *spec_dst, u32 *itag);
208
			       struct net_device *dev, u32 *spec_dst, u32 *itag, int our);
207
extern void fib_select_multipath(const struct rt_key *key, struct fib_result *res);
209
extern void fib_select_multipath(const struct rt_key *key, struct fib_result *res);
208
210
209
/* Exported by fib_semantics.c */
211
/* Exported by fib_semantics.c */
Lines 275-279 static inline void fib_res_put(struct fi Link Here
275
#endif
277
#endif
276
}
278
}
277
279
280
extern rwlock_t fib_nhflags_lock;
278
281
279
#endif  /* _NET_FIB_H */
282
#endif  /* _NET_FIB_H */
(-)linux-2.4.21/include/net/route.h (+12 lines)
Lines 49-54 struct rt_key Link Here
49
{
49
{
50
	__u32			dst;
50
	__u32			dst;
51
	__u32			src;
51
	__u32			src;
52
	__u32			lsrc;
53
	__u32			gw;
52
	int			iif;
54
	int			iif;
53
	int			oif;
55
	int			oif;
54
#ifdef CONFIG_IP_ROUTE_FWMARK
56
#ifdef CONFIG_IP_ROUTE_FWMARK
Lines 126-131 extern void ip_rt_advice(struct rtable Link Here
126
extern void		rt_cache_flush(int how);
128
extern void		rt_cache_flush(int how);
127
extern int		ip_route_output_key(struct rtable **, const struct rt_key *key);
129
extern int		ip_route_output_key(struct rtable **, const struct rt_key *key);
128
extern int		ip_route_input(struct sk_buff*, u32 dst, u32 src, u8 tos, struct net_device *devin);
130
extern int		ip_route_input(struct sk_buff*, u32 dst, u32 src, u8 tos, struct net_device *devin);
131
extern int		ip_route_input_lookup(struct sk_buff*, u32 dst, u32 src, u8 tos, struct net_device *devin, u32 lsrc);
129
extern unsigned short	ip_rt_frag_needed(struct iphdr *iph, unsigned short new_mtu);
132
extern unsigned short	ip_rt_frag_needed(struct iphdr *iph, unsigned short new_mtu);
130
extern void		ip_rt_update_pmtu(struct dst_entry *dst, unsigned mtu);
133
extern void		ip_rt_update_pmtu(struct dst_entry *dst, unsigned mtu);
131
extern void		ip_rt_send_redirect(struct sk_buff *skb);
134
extern void		ip_rt_send_redirect(struct sk_buff *skb);
Lines 146-151 static inline int ip_route_output(struct Link Here
146
}
149
}
147
150
148
151
152
static inline int
153
ip_route_output_lookup(struct rtable **rp,
154
		       u32 daddr, u32 saddr, u32 tos, int oif, u32 gw)
155
{
156
	struct rt_key key = { dst:daddr, src:saddr, gw:gw, oif:oif, tos:tos };
157
158
	return ip_route_output_key(rp, &key);
159
}
160
149
static inline void ip_rt_put(struct rtable * rt)
161
static inline void ip_rt_put(struct rtable * rt)
150
{
162
{
151
	if (rt)
163
	if (rt)
(-)linux-2.4.21/net/core/rtnetlink.c (-2 / +4 lines)
Lines 89-95 static const int rtm_min[(RTM_MAX+1-RTM_ Link Here
89
	NLMSG_LENGTH(sizeof(struct rtmsg)),
89
	NLMSG_LENGTH(sizeof(struct rtmsg)),
90
	NLMSG_LENGTH(sizeof(struct tcmsg)),
90
	NLMSG_LENGTH(sizeof(struct tcmsg)),
91
	NLMSG_LENGTH(sizeof(struct tcmsg)),
91
	NLMSG_LENGTH(sizeof(struct tcmsg)),
92
	NLMSG_LENGTH(sizeof(struct tcmsg))
92
	NLMSG_LENGTH(sizeof(struct tcmsg)),
93
	NLMSG_LENGTH(sizeof(struct arpmsg)),
93
};
94
};
94
95
95
static const int rta_max[(RTM_MAX+1-RTM_BASE)/4] =
96
static const int rta_max[(RTM_MAX+1-RTM_BASE)/4] =
Lines 101-107 static const int rta_max[(RTM_MAX+1-RTM_ Link Here
101
	RTA_MAX,
102
	RTA_MAX,
102
	TCA_MAX,
103
	TCA_MAX,
103
	TCA_MAX,
104
	TCA_MAX,
104
	TCA_MAX
105
	TCA_MAX,
106
	ARPA_MAX,
105
};
107
};
106
108
107
void __rta_fill(struct sk_buff *skb, int attrtype, int attrlen, const void *data)
109
void __rta_fill(struct sk_buff *skb, int attrtype, int attrlen, const void *data)
(-)linux-2.4.21/net/ipv4/arp.c (-11 / +662 lines)
Lines 66-71 Link Here
66
 *		Alexey Kuznetsov:	new arp state machine;
66
 *		Alexey Kuznetsov:	new arp state machine;
67
 *					now it is in net/core/neighbour.c.
67
 *					now it is in net/core/neighbour.c.
68
 *		Krzysztof Halasa:	Added Frame Relay ARP support.
68
 *		Krzysztof Halasa:	Added Frame Relay ARP support.
69
 *		Julian Anastasov:	"hidden" flag: hide the
70
 *					interface and don't reply for it
71
 *		Julian Anastasov:	ARP filtering via netlink
69
 */
72
 */
70
73
71
#include <linux/types.h>
74
#include <linux/types.h>
Lines 87-92 Link Here
87
#include <linux/skbuff.h>
90
#include <linux/skbuff.h>
88
#include <linux/proc_fs.h>
91
#include <linux/proc_fs.h>
89
#include <linux/stat.h>
92
#include <linux/stat.h>
93
#include <linux/netlink.h>
90
#include <linux/init.h>
94
#include <linux/init.h>
91
#ifdef CONFIG_SYSCTL
95
#ifdef CONFIG_SYSCTL
92
#include <linux/sysctl.h>
96
#include <linux/sysctl.h>
Lines 190-195 struct neigh_table arp_tbl = { Link Here
190
	gc_thresh3:	1024,
194
	gc_thresh3:	1024,
191
};
195
};
192
196
197
struct arpf_node {
198
	struct arpf_node *	at_next;
199
	u32			at_pref;
200
	u32			at_from;
201
	u32			at_from_mask;
202
	u32			at_to;
203
	u32			at_to_mask;
204
	u32			at_src;
205
	atomic_t		at_packets;
206
	atomic_t		at_refcnt;
207
	unsigned		at_flags;
208
	unsigned char		at_from_len;
209
	unsigned char		at_to_len;
210
	unsigned char		at_action;
211
	char			at_dead;
212
	unsigned char		at_llfrom_len;
213
	unsigned char		at_llto_len;
214
	unsigned char		at_llsrc_len;
215
	unsigned char		at_lldst_len;
216
	unsigned char		at_iif_len;
217
	unsigned char		at_oif_len;
218
	unsigned short		at__pad1;
219
	unsigned char		at_llfrom[MAX_ADDR_LEN];
220
	unsigned char		at_llto[MAX_ADDR_LEN];
221
	unsigned char		at_llsrc[MAX_ADDR_LEN];
222
	unsigned char		at_lldst[MAX_ADDR_LEN];
223
	char			at_iif[IFNAMSIZ];
224
	char			at_oif[IFNAMSIZ];
225
};
226
227
static struct arpf_node *arp_tabs[3];
228
229
static kmem_cache_t *arpf_cachep;
230
231
static rwlock_t arpf_lock = RW_LOCK_UNLOCKED;
232
233
static void
234
arpf_send(int table, struct sk_buff *skb, u32 sip, u32 tip,
235
	  unsigned char *from_hw, unsigned char *to_hw,
236
	  struct net_device *idev, struct net_device *odev);
237
193
int arp_mc_map(u32 addr, u8 *haddr, struct net_device *dev, int dir)
238
int arp_mc_map(u32 addr, u8 *haddr, struct net_device *dev, int dir)
194
{
239
{
195
	switch (dev->type) {
240
	switch (dev->type) {
Lines 317-337 static void arp_error_report(struct neig Link Here
317
static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb)
362
static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb)
318
{
363
{
319
	u32 saddr;
364
	u32 saddr;
365
	int from_skb;
366
	struct in_device *in_dev2 = NULL;
367
	struct net_device *dev2 = NULL;
320
	u8  *dst_ha = NULL;
368
	u8  *dst_ha = NULL;
321
	struct net_device *dev = neigh->dev;
369
	struct net_device *dev = neigh->dev;
322
	u32 target = *(u32*)neigh->primary_key;
370
	u32 target = *(u32*)neigh->primary_key;
323
	int probes = atomic_read(&neigh->probes);
371
	int probes = atomic_read(&neigh->probes);
372
	unsigned char tha[MAX_ADDR_LEN];
324
373
325
	if (skb && inet_addr_type(skb->nh.iph->saddr) == RTN_LOCAL)
374
	from_skb = (skb &&
375
		(dev2 = ip_dev_find(skb->nh.iph->saddr)) != NULL &&
376
		(in_dev2 = in_dev_get(dev2)) != NULL &&
377
		!IN_DEV_HIDDEN(in_dev2));
378
	if (dev2) {
379
		if (in_dev2) in_dev_put(in_dev2);
380
		dev_put(dev2);
381
	}
382
	if (from_skb)
326
		saddr = skb->nh.iph->saddr;
383
		saddr = skb->nh.iph->saddr;
327
	else
384
	else
328
		saddr = inet_select_addr(dev, target, RT_SCOPE_LINK);
385
		saddr = inet_select_addr(dev, target, RT_SCOPE_LINK);
329
386
387
	if (!saddr)
388
		return;
330
	if ((probes -= neigh->parms->ucast_probes) < 0) {
389
	if ((probes -= neigh->parms->ucast_probes) < 0) {
331
		if (!(neigh->nud_state&NUD_VALID))
390
		if (!(neigh->nud_state&NUD_VALID))
332
			printk(KERN_DEBUG "trying to ucast probe in NUD_INVALID\n");
391
			printk(KERN_DEBUG "trying to ucast probe in NUD_INVALID\n");
333
		dst_ha = neigh->ha;
392
		dst_ha = tha;
334
		read_lock_bh(&neigh->lock);
393
		read_lock_bh(&neigh->lock);
394
		memcpy(dst_ha, neigh->ha, dev->addr_len);
395
		read_unlock_bh(&neigh->lock);
335
	} else if ((probes -= neigh->parms->app_probes) < 0) {
396
	} else if ((probes -= neigh->parms->app_probes) < 0) {
336
#ifdef CONFIG_ARPD
397
#ifdef CONFIG_ARPD
337
		neigh_app_ns(neigh);
398
		neigh_app_ns(neigh);
Lines 339-348 static void arp_solicit(struct neighbour Link Here
339
		return;
400
		return;
340
	}
401
	}
341
402
342
	arp_send(ARPOP_REQUEST, ETH_P_ARP, target, dev, saddr,
403
	arpf_send(ARPA_TABLE_OUTPUT,skb,saddr,target,NULL,dst_ha,NULL,dev);
343
		 dst_ha, dev->dev_addr, NULL);
344
	if (dst_ha)
345
		read_unlock_bh(&neigh->lock);
346
}
404
}
347
405
348
static int arp_filter(__u32 sip, __u32 tip, struct net_device *dev)
406
static int arp_filter(__u32 sip, __u32 tip, struct net_device *dev)
Lines 754-762 int arp_process(struct sk_buff *skb) Link Here
754
812
755
	/* Special case: IPv4 duplicate address detection packet (RFC2131) */
813
	/* Special case: IPv4 duplicate address detection packet (RFC2131) */
756
	if (sip == 0) {
814
	if (sip == 0) {
757
		if (arp->ar_op == htons(ARPOP_REQUEST) &&
815
		int reply;
758
		    inet_addr_type(tip) == RTN_LOCAL)
816
		struct net_device *dev2 = NULL;
759
			arp_send(ARPOP_REPLY,ETH_P_ARP,tip,dev,tip,sha,dev->dev_addr,dev->dev_addr);
817
		struct in_device *in_dev2 = NULL;
818
819
		reply =
820
		    (arp->ar_op == htons(ARPOP_REQUEST) &&
821
		    (dev2 = ip_dev_find(tip)) != NULL &&
822
		    (dev2 == dev ||
823
		    ((in_dev2 = in_dev_get(dev2)) != NULL &&
824
		    !IN_DEV_HIDDEN(in_dev2))));
825
		if (dev2) {
826
		    if (in_dev2) in_dev_put(in_dev2);
827
		    dev_put(dev2);
828
		    if (reply)
829
			arpf_send(ARPA_TABLE_INPUT,skb,sip,tip,sha,tha,dev,NULL);
830
		}
760
		goto out;
831
		goto out;
761
	}
832
	}
762
833
Lines 770-779 int arp_process(struct sk_buff *skb) Link Here
770
			n = neigh_event_ns(&arp_tbl, sha, &sip, dev);
841
			n = neigh_event_ns(&arp_tbl, sha, &sip, dev);
771
			if (n) {
842
			if (n) {
772
				int dont_send = 0;
843
				int dont_send = 0;
844
				if (ipv4_devconf.hidden &&
845
				    skb->pkt_type != PACKET_HOST) {
846
					struct net_device *dev2 = NULL;
847
					struct in_device *in_dev2 = NULL;
848
849
					dont_send |=
850
					  ((dev2 = ip_dev_find(tip)) != NULL &&
851
					  dev2 != dev &&
852
					  (in_dev2=in_dev_get(dev2)) != NULL &&
853
					  IN_DEV_HIDDEN(in_dev2));
854
					if (dev2) {
855
					    if (in_dev2) in_dev_put(in_dev2);
856
					    dev_put(dev2);
857
					}
858
				}
773
				if (IN_DEV_ARPFILTER(in_dev))
859
				if (IN_DEV_ARPFILTER(in_dev))
774
					dont_send |= arp_filter(sip,tip,dev); 
860
					dont_send |= arp_filter(sip,tip,dev); 
775
				if (!dont_send)
861
				if (!dont_send)
776
					arp_send(ARPOP_REPLY,ETH_P_ARP,sip,dev,tip,sha,dev->dev_addr,sha);
862
					arpf_send(ARPA_TABLE_INPUT,skb,
863
						  sip,tip,sha,tha,dev,NULL);
777
864
778
				neigh_release(n);
865
				neigh_release(n);
779
			}
866
			}
Lines 789-795 int arp_process(struct sk_buff *skb) Link Here
789
				if (skb->stamp.tv_sec == 0 ||
876
				if (skb->stamp.tv_sec == 0 ||
790
				    skb->pkt_type == PACKET_HOST ||
877
				    skb->pkt_type == PACKET_HOST ||
791
				    in_dev->arp_parms->proxy_delay == 0) {
878
				    in_dev->arp_parms->proxy_delay == 0) {
792
					arp_send(ARPOP_REPLY,ETH_P_ARP,sip,dev,tip,sha,dev->dev_addr,sha);
879
					arpf_send(ARPA_TABLE_FORWARD,skb,
880
						  sip,tip,sha,tha,dev,
881
						  rt->u.dst.dev);
793
				} else {
882
				} else {
794
					pneigh_enqueue(&arp_tbl, in_dev->arp_parms, skb);
883
					pneigh_enqueue(&arp_tbl, in_dev->arp_parms, skb);
795
					in_dev_put(in_dev);
884
					in_dev_put(in_dev);
Lines 1221-1226 void arp_ifdown(struct net_device *dev) Link Here
1221
}
1310
}
1222
1311
1223
1312
1313
static void arpf_destroy(struct arpf_node *afp)
1314
{
1315
	if (!afp->at_dead) {
1316
		printk(KERN_ERR "Destroying alive arp table node %p from %08lx\n", afp,
1317
		       *(((unsigned long*)&afp)-1));
1318
		return;
1319
	}
1320
	kmem_cache_free(arpf_cachep, afp);
1321
}
1322
1323
static inline void arpf_put(struct arpf_node *afp)
1324
{
1325
	if (atomic_dec_and_test(&afp->at_refcnt))
1326
		arpf_destroy(afp);
1327
}
1328
1329
static inline struct arpf_node *
1330
arpf_lookup(int table, struct sk_buff *skb, u32 sip, u32 tip,
1331
	    unsigned char *from_hw, unsigned char *to_hw,
1332
	    struct net_device *idev, struct net_device *odev)
1333
{
1334
	int sz_iif = idev? strlen(idev->name) : 0;
1335
	int sz_oif = odev? strlen(odev->name) : 0;
1336
	int alen;
1337
	struct arpf_node *afp;
1338
1339
	if (ARPA_TABLE_OUTPUT != table) {
1340
		alen = idev->addr_len;
1341
	} else {
1342
		if (!from_hw) from_hw = odev->dev_addr;
1343
		if (!to_hw) to_hw = odev->broadcast;
1344
		alen = odev->addr_len;
1345
	}
1346
1347
	read_lock(&arpf_lock);
1348
	for (afp = arp_tabs[table]; afp; afp = afp->at_next) {
1349
		if ((tip ^ afp->at_to) & afp->at_to_mask)
1350
			continue;
1351
		if ((sip ^ afp->at_from) & afp->at_from_mask)
1352
			continue;
1353
		if (afp->at_llfrom_len &&
1354
		    (afp->at_llfrom_len > alen ||
1355
		     memcmp(from_hw, afp->at_llfrom, afp->at_llfrom_len)))
1356
			continue;
1357
		if (afp->at_llto_len &&
1358
		    (afp->at_llto_len > alen ||
1359
		     memcmp(to_hw, afp->at_llto, afp->at_llto_len)))
1360
			continue;
1361
		if (afp->at_iif_len &&
1362
		    (afp->at_iif_len > sz_iif ||
1363
		     memcmp(afp->at_iif, idev->name, afp->at_iif_len) ||
1364
		     (sz_iif != afp->at_iif_len &&
1365
		      !(afp->at_flags & ARPM_F_WILDIIF))))
1366
			continue;
1367
		if (afp->at_oif_len &&
1368
		    (afp->at_oif_len > sz_oif ||
1369
		     memcmp(afp->at_oif, odev->name, afp->at_oif_len) ||
1370
		     (sz_oif != afp->at_oif_len &&
1371
		      !(afp->at_flags & ARPM_F_WILDOIF))))
1372
			continue;
1373
		if (afp->at_flags & ARPM_F_BROADCAST &&
1374
		    skb->pkt_type == PACKET_HOST)
1375
			continue;
1376
		if (afp->at_flags & ARPM_F_UNICAST &&
1377
		    skb->pkt_type != PACKET_HOST)
1378
			continue;
1379
		if (afp->at_llsrc_len && afp->at_llsrc_len != alen)
1380
			continue;
1381
		if (afp->at_lldst_len && afp->at_lldst_len != alen)
1382
			continue;
1383
		atomic_inc(&afp->at_packets);
1384
		break;
1385
	}
1386
	read_unlock(&arpf_lock);
1387
	return afp;
1388
}
1389
1390
static void
1391
arpf_send(int table, struct sk_buff *skb, u32 sip, u32 tip,
1392
	  unsigned char *from_hw, unsigned char *to_hw,
1393
	  struct net_device *idev, struct net_device *odev)
1394
{
1395
	struct arpf_node *afp = NULL;
1396
1397
	if (!arp_tabs[table] ||
1398
	    !(afp = arpf_lookup(table, skb, sip, tip,
1399
				from_hw, to_hw, idev, odev))) {
1400
		switch (table) {
1401
		case ARPA_TABLE_INPUT:
1402
			if (!sip) {
1403
				arp_send(ARPOP_REPLY, ETH_P_ARP, tip, idev, tip,
1404
					 from_hw, idev->dev_addr,
1405
					 idev->dev_addr);
1406
				break;
1407
			}
1408
			/* continue */
1409
		case ARPA_TABLE_FORWARD:
1410
			arp_send(ARPOP_REPLY, ETH_P_ARP, sip, idev, tip,
1411
				 from_hw, idev->dev_addr, from_hw);
1412
			break;
1413
		case ARPA_TABLE_OUTPUT:
1414
			arp_send(ARPOP_REQUEST, ETH_P_ARP, tip, odev, sip,
1415
				 to_hw, odev->dev_addr, NULL);
1416
			break;
1417
		}
1418
		return;
1419
	}
1420
1421
	/* deny? */
1422
	if (!afp->at_action) goto out;
1423
1424
	switch (table) {
1425
	case ARPA_TABLE_INPUT:
1426
		if (!sip) {
1427
			arp_send(ARPOP_REPLY, ETH_P_ARP, tip, idev, tip,
1428
				from_hw,
1429
				afp->at_llsrc_len?afp->at_llsrc:idev->dev_addr,
1430
				afp->at_llsrc_len?afp->at_llsrc:idev->dev_addr);
1431
			break;
1432
		}
1433
		/* continue */
1434
	case ARPA_TABLE_FORWARD:
1435
		arp_send(ARPOP_REPLY, ETH_P_ARP, sip, idev, tip,
1436
			 afp->at_lldst_len?afp->at_lldst:from_hw,
1437
			 afp->at_llsrc_len?afp->at_llsrc:idev->dev_addr,
1438
			 afp->at_lldst_len?afp->at_lldst:from_hw);
1439
		break;
1440
	case ARPA_TABLE_OUTPUT:
1441
		if (afp->at_flags & ARPM_F_PREFSRC && afp->at_src == 0) {
1442
			struct rtable *rt;
1443
1444
			if (ip_route_output(&rt, tip, 0, 0, odev->ifindex) < 0)
1445
				break;
1446
			sip = rt->rt_src;
1447
			ip_rt_put(rt);
1448
			if (!sip)
1449
				break;
1450
		}
1451
		arp_send(ARPOP_REQUEST, ETH_P_ARP, tip, odev, afp->at_src?:sip,
1452
			 afp->at_lldst_len?afp->at_lldst:to_hw,
1453
			 afp->at_llsrc_len?afp->at_llsrc:odev->dev_addr,
1454
			 NULL);
1455
		break;
1456
	}
1457
1458
out:
1459
	arpf_put(afp);
1460
}
1461
1462
static int
1463
arpf_fill_node(struct sk_buff *skb, u32 pid, u32 seq, unsigned flags,
1464
	       int event, int table, struct arpf_node *afp)
1465
{
1466
	struct arpmsg	*am;
1467
	struct nlmsghdr	*nlh;
1468
	unsigned char	*b = skb->tail;
1469
	u32 packets = atomic_read(&afp->at_packets);
1470
1471
	nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*am));
1472
	nlh->nlmsg_flags = flags;
1473
	am = NLMSG_DATA(nlh);
1474
	am->arpm_family = AF_UNSPEC;
1475
	am->arpm_table = table;
1476
	am->arpm_action = afp->at_action;
1477
	am->arpm_from_len = afp->at_from_len;
1478
	am->arpm_to_len = afp->at_to_len;
1479
	am->arpm_pref = afp->at_pref;
1480
	am->arpm_flags = afp->at_flags;
1481
	if (afp->at_from_len)
1482
		RTA_PUT(skb, ARPA_FROM, 4, &afp->at_from);
1483
	if (afp->at_to_len)
1484
		RTA_PUT(skb, ARPA_TO, 4, &afp->at_to);
1485
	if (afp->at_src || afp->at_flags & ARPM_F_PREFSRC)
1486
		RTA_PUT(skb, ARPA_SRC, 4, &afp->at_src);
1487
	if (afp->at_iif[0])
1488
		RTA_PUT(skb, ARPA_IIF, sizeof(afp->at_iif), afp->at_iif);
1489
	if (afp->at_oif[0])
1490
		RTA_PUT(skb, ARPA_OIF, sizeof(afp->at_oif), afp->at_oif);
1491
	if (afp->at_llfrom_len)
1492
		RTA_PUT(skb, ARPA_LLFROM, afp->at_llfrom_len, afp->at_llfrom);
1493
	if (afp->at_llto_len)
1494
		RTA_PUT(skb, ARPA_LLTO, afp->at_llto_len, afp->at_llto);
1495
	if (afp->at_llsrc_len)
1496
		RTA_PUT(skb, ARPA_LLSRC, afp->at_llsrc_len, afp->at_llsrc);
1497
	if (afp->at_lldst_len)
1498
		RTA_PUT(skb, ARPA_LLDST, afp->at_lldst_len, afp->at_lldst);
1499
	RTA_PUT(skb, ARPA_PACKETS, 4, &packets);
1500
	nlh->nlmsg_len = skb->tail - b;
1501
	return skb->len;
1502
1503
nlmsg_failure:
1504
rtattr_failure:
1505
	skb_trim(skb, b - skb->data);
1506
	return -1;
1507
}
1508
1509
static int
1510
arpmsg_notify(struct sk_buff *oskb, struct nlmsghdr *n, int table,
1511
	      struct arpf_node *afp, int event)
1512
{
1513
	struct sk_buff *skb;
1514
	u32 pid = oskb ? NETLINK_CB(oskb).pid : 0;
1515
	int size = NLMSG_SPACE(sizeof(struct arpmsg)+256);
1516
1517
	skb = alloc_skb(size, GFP_KERNEL);
1518
	if (!skb)
1519
		return -ENOBUFS;
1520
1521
	if (arpf_fill_node(skb, pid, n->nlmsg_seq, 0, event, table, afp) <= 0) {
1522
		kfree_skb(skb);
1523
		return -EINVAL;
1524
	}
1525
1526
	return rtnetlink_send(skb, pid, RTMGRP_ARP, n->nlmsg_flags&NLM_F_ECHO);
1527
}
1528
1529
static inline int
1530
arpf_str_size(int a, struct rtattr **rta, int maxlen)
1531
{
1532
	int size = 0;
1533
1534
	if (rta[a-1] && (size = RTA_PAYLOAD(rta[a-1]))) {
1535
		if (size > maxlen)
1536
			size = maxlen;
1537
	}
1538
	return size;
1539
}
1540
1541
static inline int
1542
arpf_get_str(int a, struct rtattr **rta, unsigned char *p,
1543
	     int maxlen, unsigned char *l)
1544
{
1545
	int size = arpf_str_size(a, rta, maxlen);
1546
1547
	if (size) {
1548
		memcpy(p, RTA_DATA(rta[a-1]), size);
1549
		*l = size;
1550
	}
1551
	return size;
1552
}
1553
1554
#define ARPF_MATCH_U32(ind, field)	(			\
1555
	(!rta[ind-1] && r->at_ ## field == 0) ||		\
1556
	(rta[ind-1] &&						\
1557
	 *(u32*) RTA_DATA(rta[ind-1]) == r->at_ ## field))
1558
1559
#define ARPF_MATCH_STR(ind, field)	(			\
1560
	(!rta[ind-1] && r->at_ ## field ## _len == 0) ||	\
1561
	(rta[ind-1] && r->at_ ## field ## _len &&		\
1562
	 r->at_ ## field ## _len < RTA_PAYLOAD(rta[ind-1]) &&	\
1563
	 strcmp(RTA_DATA(rta[ind-1]), r->at_ ## field) == 0))
1564
1565
#define ARPF_MATCH_DATA(ind, field)	(			\
1566
	(!rta[ind-1] && r->at_ ## field ## _len == 0) ||	\
1567
	(rta[ind-1] && r->at_ ## field ## _len &&		\
1568
	 r->at_ ## field ## _len == RTA_PAYLOAD(rta[ind-1]) &&	\
1569
	 memcmp(RTA_DATA(rta[ind-1]), &r->at_ ## field,		\
1570
		r->at_ ## field ## _len) == 0))
1571
1572
/* RTM_NEWARPRULE/RTM_DELARPRULE/RTM_GETARPRULE */
1573
1574
int arpf_rule_ctl(struct sk_buff *skb, struct nlmsghdr* n, void *arg)
1575
{
1576
	struct rtattr **rta = arg;
1577
	struct arpmsg *am = NLMSG_DATA(n);
1578
	struct arpf_node *r, **rp, **prevp = 0, **delp = 0, *newp = 0;
1579
	unsigned pref = 1;
1580
	int size, ret = -EINVAL;
1581
1582
	if (am->arpm_table >= sizeof(arp_tabs)/sizeof(arp_tabs[0]))
1583
		goto out;
1584
	if (!((~am->arpm_flags) & (ARPM_F_BROADCAST|ARPM_F_UNICAST)))
1585
		goto out;
1586
	if (am->arpm_action > 1)
1587
		goto out;
1588
	if (am->arpm_to_len > 32 || am->arpm_from_len > 32)
1589
		goto out;
1590
	if (am->arpm_flags & ARPM_F_WILDIIF &&
1591
	    (!rta[ARPA_IIF-1] || !RTA_PAYLOAD(rta[ARPA_IIF-1]) ||
1592
	    !*(char*)RTA_DATA(rta[ARPA_IIF-1])))
1593
		am->arpm_flags &= ~ARPM_F_WILDIIF;
1594
	if (am->arpm_flags & ARPM_F_WILDOIF &&
1595
	    (!rta[ARPA_OIF-1] || !RTA_PAYLOAD(rta[ARPA_OIF-1]) ||
1596
	    !*(char*)RTA_DATA(rta[ARPA_OIF-1])))
1597
		am->arpm_flags &= ~ARPM_F_WILDOIF;
1598
	switch (am->arpm_table) {
1599
	case ARPA_TABLE_INPUT:
1600
		if (rta[ARPA_SRC-1] || rta[ARPA_OIF-1])
1601
			goto out;
1602
		break;
1603
	case ARPA_TABLE_OUTPUT:
1604
		if (rta[ARPA_IIF-1])
1605
			goto out;
1606
		if (am->arpm_flags & (ARPM_F_BROADCAST|ARPM_F_UNICAST))
1607
			goto out;
1608
		break;
1609
	case ARPA_TABLE_FORWARD:
1610
		if (rta[ARPA_SRC-1])
1611
			goto out;
1612
		break;
1613
	}
1614
	if (rta[ARPA_SRC-1] && !*(u32*) RTA_DATA(rta[ARPA_SRC-1]))
1615
		am->arpm_flags |= ARPM_F_PREFSRC;
1616
	else
1617
		am->arpm_flags &= ~ARPM_F_PREFSRC;
1618
1619
	for (rp = &arp_tabs[am->arpm_table]; (r=*rp) != NULL; rp=&r->at_next) {
1620
		if (pref < r->at_pref)
1621
			prevp = rp;
1622
		if (am->arpm_pref == r->at_pref ||
1623
		    (!am->arpm_pref &&
1624
		     am->arpm_to_len == r->at_to_len &&
1625
		     am->arpm_from_len == r->at_from_len &&
1626
		     !((am->arpm_flags ^ r->at_flags) &
1627
		       (ARPM_F_BROADCAST | ARPM_F_UNICAST |
1628
		        ARPM_F_WILDIIF | ARPM_F_WILDOIF)) &&
1629
		     ARPF_MATCH_U32(ARPA_TO, to) &&
1630
		     ARPF_MATCH_U32(ARPA_FROM, from) &&
1631
		     ARPF_MATCH_DATA(ARPA_LLFROM, llfrom) &&
1632
		     ARPF_MATCH_DATA(ARPA_LLTO, llto) &&
1633
		     ARPF_MATCH_STR(ARPA_IIF, iif) &&
1634
		     ARPF_MATCH_STR(ARPA_OIF, oif) &&
1635
		     (n->nlmsg_type != RTM_DELARPRULE ||
1636
		      /* DEL matches more keys */
1637
		      (am->arpm_flags == r->at_flags &&
1638
		       am->arpm_action == r->at_action &&
1639
		       ARPF_MATCH_U32(ARPA_SRC, src) &&
1640
		       ARPF_MATCH_DATA(ARPA_LLSRC, llsrc) &&
1641
		       ARPF_MATCH_DATA(ARPA_LLDST, lldst)
1642
		      )
1643
		     )
1644
		    )
1645
		   )
1646
			break;
1647
		if (am->arpm_pref && r->at_pref > am->arpm_pref) {
1648
			r = NULL;
1649
			break;
1650
		}
1651
		pref = r->at_pref+1;
1652
	}
1653
1654
	/*
1655
	 * r=NULL:	*rp != NULL (stopped before next pref), pref: not valid
1656
	 *		*rp == NULL (not found), pref: ready to use
1657
	 * r!=NULL:	found, pref: not valid
1658
	 *
1659
	 * prevp=NULL:	no free slot
1660
	 * prevp!=NULL:	free slot for rule
1661
	 */
1662
1663
	if (n->nlmsg_type == RTM_DELARPRULE) {
1664
		if (!r)
1665
			return -ESRCH;
1666
		delp = rp;
1667
		goto dequeue;
1668
	}
1669
1670
	if (r) {
1671
		/* Existing rule */
1672
		ret = -EEXIST;
1673
		if (n->nlmsg_flags&NLM_F_EXCL)
1674
			goto out;
1675
1676
		if (n->nlmsg_flags&NLM_F_REPLACE) {
1677
			pref = r->at_pref;
1678
			prevp = delp = rp;
1679
			goto replace;
1680
		}
1681
	}
1682
1683
	if (n->nlmsg_flags&NLM_F_APPEND) {
1684
		if (r) {
1685
			pref = r->at_pref+1;
1686
			for (rp=&r->at_next; (r=*rp) != NULL; rp=&r->at_next) {
1687
				if (pref != r->at_pref)
1688
					break;
1689
				pref ++;
1690
			}
1691
			ret = -EBUSY;
1692
			if (!pref)
1693
				goto out;
1694
		} else if (am->arpm_pref)
1695
			pref = am->arpm_pref;
1696
		prevp = rp;
1697
	}
1698
1699
	if (!(n->nlmsg_flags&NLM_F_CREATE)) {
1700
		ret = -ENOENT;
1701
		if (n->nlmsg_flags&NLM_F_EXCL || r)
1702
			ret = 0;
1703
		goto out;
1704
	}
1705
1706
	if (!(n->nlmsg_flags&NLM_F_APPEND)) {
1707
		if (!prevp) {
1708
			ret = -EBUSY;
1709
			if (r || *rp ||
1710
			    (!am->arpm_pref && arp_tabs[am->arpm_table]))
1711
				goto out;
1712
			prevp = rp;
1713
			pref = am->arpm_pref? : 99;
1714
		} else {
1715
			if (r || !am->arpm_pref) {
1716
				pref = (*prevp)->at_pref - 1;
1717
				if (am->arpm_pref && am->arpm_pref < pref)
1718
					pref = am->arpm_pref;
1719
			} else {
1720
				prevp = rp;
1721
				pref = am->arpm_pref;
1722
			}
1723
		}
1724
	}
1725
1726
replace:
1727
1728
	ret = -ENOMEM;
1729
	r = kmem_cache_alloc(arpf_cachep, SLAB_KERNEL);
1730
	if (!r)
1731
		return ret;
1732
	memset(r, 0, sizeof(*r));
1733
1734
	arpf_get_str(ARPA_LLFROM, rta, r->at_llfrom, MAX_ADDR_LEN,
1735
		     &r->at_llfrom_len);
1736
	arpf_get_str(ARPA_LLTO, rta, r->at_llto, MAX_ADDR_LEN,
1737
		     &r->at_llto_len);
1738
	arpf_get_str(ARPA_LLSRC, rta, r->at_llsrc, MAX_ADDR_LEN,
1739
		     &r->at_llsrc_len);
1740
	arpf_get_str(ARPA_LLDST, rta, r->at_lldst, MAX_ADDR_LEN,
1741
		     &r->at_lldst_len);
1742
1743
	if (delp)
1744
		r->at_next = (*delp)->at_next;
1745
	else if (*prevp)
1746
		r->at_next = *prevp;
1747
1748
	r->at_pref = pref;
1749
	r->at_from_len = am->arpm_from_len;
1750
	r->at_from_mask = inet_make_mask(r->at_from_len);
1751
	if (rta[ARPA_FROM-1])
1752
		r->at_from = *(u32*) RTA_DATA(rta[ARPA_FROM-1]);
1753
	r->at_from &= r->at_from_mask;
1754
	r->at_to_len = am->arpm_to_len;
1755
	r->at_to_mask = inet_make_mask(r->at_to_len);
1756
	if (rta[ARPA_TO-1])
1757
		r->at_to = *(u32*) RTA_DATA(rta[ARPA_TO-1]);
1758
	r->at_to &= r->at_to_mask;
1759
	if (rta[ARPA_SRC-1])
1760
		r->at_src = *(u32*) RTA_DATA(rta[ARPA_SRC-1]);
1761
	if (rta[ARPA_PACKETS-1]) {
1762
		u32 packets = *(u32*) RTA_DATA(rta[ARPA_PACKETS-1]);
1763
		atomic_set(&r->at_packets, packets);
1764
	}
1765
	atomic_set(&r->at_refcnt, 1);
1766
	r->at_flags = am->arpm_flags;
1767
	r->at_action = am->arpm_action;
1768
1769
	if (rta[ARPA_IIF-1] && (size = RTA_PAYLOAD(rta[ARPA_IIF-1]))) {
1770
		if (size >= sizeof(r->at_iif))
1771
			size = sizeof(r->at_iif)-1;
1772
		memcpy(r->at_iif, RTA_DATA(rta[ARPA_IIF-1]), size);
1773
		r->at_iif_len = strlen(r->at_iif);
1774
	}
1775
	if (rta[ARPA_OIF-1] && (size = RTA_PAYLOAD(rta[ARPA_OIF-1]))) {
1776
		if (size >= sizeof(r->at_oif))
1777
			size = sizeof(r->at_oif)-1;
1778
		memcpy(r->at_oif, RTA_DATA(rta[ARPA_OIF-1]), size);
1779
		r->at_oif_len = strlen(r->at_oif);
1780
	}
1781
1782
	newp = r;
1783
1784
dequeue:
1785
1786
	if (delp) {
1787
		r = *delp;
1788
		write_lock_bh(&arpf_lock);
1789
		if (newp) {
1790
			if (!rta[ARPA_PACKETS-1])
1791
				atomic_set(&newp->at_packets,
1792
					atomic_read(&r->at_packets));
1793
			*delp = newp;
1794
		} else {
1795
			*delp = r->at_next;
1796
		}
1797
		r->at_dead = 1;
1798
		write_unlock_bh(&arpf_lock);
1799
		arpmsg_notify(skb, n, am->arpm_table, r, RTM_DELARPRULE);
1800
		arpf_put(r);
1801
		prevp = 0;
1802
	}
1803
1804
	if (newp) {
1805
		if (prevp) {
1806
			write_lock_bh(&arpf_lock);
1807
			*prevp = newp;
1808
			write_unlock_bh(&arpf_lock);
1809
		}
1810
		arpmsg_notify(skb, n, am->arpm_table, newp, RTM_NEWARPRULE);
1811
	}
1812
1813
	ret = 0;
1814
1815
out:
1816
	return ret;
1817
}
1818
1819
int arpf_dump_table(int t, struct sk_buff *skb, struct netlink_callback *cb)
1820
{
1821
	int idx, ret = -1;
1822
	struct arpf_node *afp;
1823
	int s_idx = cb->args[1];
1824
1825
	for (idx=0, afp = arp_tabs[t]; afp; afp = afp->at_next, idx++) {
1826
		if (idx < s_idx)
1827
			continue;
1828
		if (arpf_fill_node(skb, NETLINK_CB(cb->skb).pid,
1829
		    cb->nlh->nlmsg_seq, NLM_F_MULTI, RTM_NEWARPRULE, t, afp) < 0)
1830
			goto out;
1831
	}
1832
1833
	ret = skb->len;
1834
1835
out:
1836
	cb->args[1] = idx;
1837
1838
	return ret;
1839
}
1840
1841
int arpf_dump_rules(struct sk_buff *skb, struct netlink_callback *cb)
1842
{
1843
	int idx;
1844
	int s_idx = cb->args[0];
1845
1846
	read_lock_bh(&arpf_lock);
1847
	for (idx = 0; idx < sizeof(arp_tabs)/sizeof(arp_tabs[0]); idx++) {
1848
		if (idx < s_idx)
1849
			continue;
1850
		if (idx > s_idx)
1851
			memset(&cb->args[1], 0, sizeof(cb->args)-1*sizeof(cb->args[0]));
1852
		if (arpf_dump_table(idx, skb, cb) < 0)
1853
			break;
1854
	}
1855
	read_unlock_bh(&arpf_lock);
1856
	cb->args[0] = idx;
1857
1858
	return skb->len;
1859
}
1860
1224
/*
1861
/*
1225
 *	Called once on startup.
1862
 *	Called once on startup.
1226
 */
1863
 */
Lines 1233-1238 static struct packet_type arp_packet_typ Link Here
1233
1870
1234
void __init arp_init (void)
1871
void __init arp_init (void)
1235
{
1872
{
1873
	struct rtnetlink_link *link_p = rtnetlink_links[PF_UNSPEC];
1874
1875
	arpf_cachep = kmem_cache_create("ip_arpf_cache",
1876
					sizeof(struct arpf_node), 0,
1877
					SLAB_HWCACHE_ALIGN, NULL, NULL);
1878
	if (!arpf_cachep)
1879
		panic("IP: failed to allocate ip_arpf_cache\n");
1880
1881
	if (link_p) {
1882
		link_p[RTM_NEWARPRULE-RTM_BASE].doit = arpf_rule_ctl;
1883
		link_p[RTM_DELARPRULE-RTM_BASE].doit = arpf_rule_ctl;
1884
		link_p[RTM_GETARPRULE-RTM_BASE].dumpit = arpf_dump_rules;
1885
	}
1886
1236
	neigh_table_init(&arp_tbl);
1887
	neigh_table_init(&arp_tbl);
1237
1888
1238
	dev_add_pack(&arp_packet_type);
1889
	dev_add_pack(&arp_packet_type);
(-)linux-2.4.21/net/ipv4/devinet.c (-2 / +12 lines)
Lines 756-762 u32 inet_select_addr(const struct net_de Link Here
756
756
757
		read_lock(&in_dev->lock);
757
		read_lock(&in_dev->lock);
758
		for_primary_ifa(in_dev) {
758
		for_primary_ifa(in_dev) {
759
			if (ifa->ifa_scope != RT_SCOPE_LINK &&
759
			if (!IN_DEV_HIDDEN(in_dev) &&
760
			    ifa->ifa_scope != RT_SCOPE_LINK &&
760
			    ifa->ifa_scope <= scope) {
761
			    ifa->ifa_scope <= scope) {
761
				read_unlock(&in_dev->lock);
762
				read_unlock(&in_dev->lock);
762
				read_unlock(&inetdev_lock);
763
				read_unlock(&inetdev_lock);
Lines 1056-1062 int devinet_sysctl_forward(ctl_table *ct Link Here
1056
static struct devinet_sysctl_table
1057
static struct devinet_sysctl_table
1057
{
1058
{
1058
	struct ctl_table_header *sysctl_header;
1059
	struct ctl_table_header *sysctl_header;
1059
	ctl_table devinet_vars[15];
1060
	ctl_table devinet_vars[18];
1060
	ctl_table devinet_dev[2];
1061
	ctl_table devinet_dev[2];
1061
	ctl_table devinet_conf_dir[2];
1062
	ctl_table devinet_conf_dir[2];
1062
	ctl_table devinet_proto_dir[2];
1063
	ctl_table devinet_proto_dir[2];
Lines 1093-1098 static struct devinet_sysctl_table Link Here
1093
	{NET_IPV4_CONF_MEDIUM_ID, "medium_id",
1094
	{NET_IPV4_CONF_MEDIUM_ID, "medium_id",
1094
         &ipv4_devconf.medium_id, sizeof(int), 0644, NULL,
1095
         &ipv4_devconf.medium_id, sizeof(int), 0644, NULL,
1095
         &proc_dointvec},
1096
         &proc_dointvec},
1097
	{NET_IPV4_CONF_RP_FILTER_MASK, "rp_filter_mask",
1098
         &ipv4_devconf.rp_filter_mask, sizeof(int), 0644, NULL,
1099
         &proc_dointvec},
1096
	{NET_IPV4_CONF_BOOTP_RELAY, "bootp_relay",
1100
	{NET_IPV4_CONF_BOOTP_RELAY, "bootp_relay",
1097
         &ipv4_devconf.bootp_relay, sizeof(int), 0644, NULL,
1101
         &ipv4_devconf.bootp_relay, sizeof(int), 0644, NULL,
1098
         &proc_dointvec},
1102
         &proc_dointvec},
Lines 1102-1110 static struct devinet_sysctl_table Link Here
1102
	{NET_IPV4_CONF_TAG, "tag",
1106
	{NET_IPV4_CONF_TAG, "tag",
1103
	 &ipv4_devconf.tag, sizeof(int), 0644, NULL,
1107
	 &ipv4_devconf.tag, sizeof(int), 0644, NULL,
1104
	 &proc_dointvec},
1108
	 &proc_dointvec},
1109
	{NET_IPV4_CONF_HIDDEN, "hidden",
1110
	 &ipv4_devconf.hidden, sizeof(int), 0644, NULL,
1111
	 &proc_dointvec},
1105
	{NET_IPV4_CONF_ARPFILTER, "arp_filter",
1112
	{NET_IPV4_CONF_ARPFILTER, "arp_filter",
1106
	 &ipv4_devconf.arp_filter, sizeof(int), 0644, NULL,
1113
	 &ipv4_devconf.arp_filter, sizeof(int), 0644, NULL,
1107
	 &proc_dointvec},
1114
	 &proc_dointvec},
1115
	{NET_IPV4_CONF_FORWARD_SHARED, "forward_shared",
1116
	 &ipv4_devconf.forward_shared, sizeof(int), 0644, NULL,
1117
	 &proc_dointvec},
1108
	 {0}},
1118
	 {0}},
1109
1119
1110
	{{NET_PROTO_CONF_ALL, "all", NULL, 0, 0555, devinet_sysctl.devinet_vars},{0}},
1120
	{{NET_PROTO_CONF_ALL, "all", NULL, 0, 0555, devinet_sysctl.devinet_vars},{0}},
(-)linux-2.4.21/net/ipv4/fib_frontend.c (-13 / +43 lines)
Lines 54-59 Link Here
54
struct fib_table *local_table;
54
struct fib_table *local_table;
55
struct fib_table *main_table;
55
struct fib_table *main_table;
56
56
57
#define FIB_RES_TABLE(r) (RT_TABLE_MAIN)
58
57
#else
59
#else
58
60
59
#define RT_TABLE_MIN 1
61
#define RT_TABLE_MIN 1
Lines 71-76 struct fib_table *__fib_new_table(int id Link Here
71
	return tb;
73
	return tb;
72
}
74
}
73
75
76
#define FIB_RES_TABLE(r) (fib_result_table(r))
74
77
75
#endif /* CONFIG_IP_MULTIPLE_TABLES */
78
#endif /* CONFIG_IP_MULTIPLE_TABLES */
76
79
Lines 204-221 unsigned inet_addr_type(u32 addr) Link Here
204
 */
207
 */
205
208
206
int fib_validate_source(u32 src, u32 dst, u8 tos, int oif,
209
int fib_validate_source(u32 src, u32 dst, u8 tos, int oif,
207
			struct net_device *dev, u32 *spec_dst, u32 *itag)
210
			struct net_device *dev, u32 *spec_dst, u32 *itag,
211
			int our)
208
{
212
{
209
	struct in_device *in_dev;
213
	struct in_device *in_dev;
210
	struct rt_key key;
214
	struct rt_key key;
211
	struct fib_result res;
215
	struct fib_result res;
216
	int table;
217
	unsigned char prefixlen;
218
	unsigned char scope;
212
	int no_addr, rpf;
219
	int no_addr, rpf;
220
	unsigned rpf_mask = 0;
213
	int ret;
221
	int ret;
222
	int fwdsh = 0;
214
223
215
	key.dst = src;
224
	key.dst = src;
216
	key.src = dst;
225
	key.src = dst;
217
	key.tos = tos;
226
	key.tos = tos;
218
	key.oif = 0;
227
	key.oif = 0;
228
	key.gw	= 0;
219
	key.iif = oif;
229
	key.iif = oif;
220
	key.scope = RT_SCOPE_UNIVERSE;
230
	key.scope = RT_SCOPE_UNIVERSE;
221
231
Lines 225-230 int fib_validate_source(u32 src, u32 dst Link Here
225
	if (in_dev) {
235
	if (in_dev) {
226
		no_addr = in_dev->ifa_list == NULL;
236
		no_addr = in_dev->ifa_list == NULL;
227
		rpf = IN_DEV_RPFILTER(in_dev);
237
		rpf = IN_DEV_RPFILTER(in_dev);
238
		fwdsh = IN_DEV_FORWARD_SHARED(in_dev);
239
		rpf_mask = IN_DEV_RPFILTER_MASK(in_dev);
228
	}
240
	}
229
	read_unlock(&inetdev_lock);
241
	read_unlock(&inetdev_lock);
230
242
Lines 233-267 int fib_validate_source(u32 src, u32 dst Link Here
233
245
234
	if (fib_lookup(&key, &res))
246
	if (fib_lookup(&key, &res))
235
		goto last_resort;
247
		goto last_resort;
236
	if (res.type != RTN_UNICAST)
248
	if (fwdsh) {
249
		fwdsh = (res.type == RTN_LOCAL && !our);
250
		if (fwdsh)
251
			rpf = 0;
252
	}
253
	if (res.type != RTN_UNICAST && !fwdsh)
237
		goto e_inval_res;
254
		goto e_inval_res;
238
	*spec_dst = FIB_RES_PREFSRC(res);
255
	*spec_dst = FIB_RES_PREFSRC(res);
239
	fib_combine_itag(itag, &res);
256
	fib_combine_itag(itag, &res);
240
#ifdef CONFIG_IP_ROUTE_MULTIPATH
241
	if (FIB_RES_DEV(res) == dev || res.fi->fib_nhs > 1)
242
#else
243
	if (FIB_RES_DEV(res) == dev)
257
	if (FIB_RES_DEV(res) == dev)
244
#endif
245
	{
258
	{
246
		ret = FIB_RES_NH(res).nh_scope >= RT_SCOPE_HOST;
259
		ret = FIB_RES_NH(res).nh_scope >= RT_SCOPE_HOST;
247
		fib_res_put(&res);
260
		fib_res_put(&res);
248
		return ret;
261
		return ret;
249
	}
262
	}
263
	if (rpf_mask && rpf) {
264
		int omi = 0;
265
266
		read_lock(&inetdev_lock);
267
		in_dev = __in_dev_get(FIB_RES_DEV(res));
268
		if (in_dev)
269
			omi = IN_DEV_MEDIUM_ID(in_dev);
270
		read_unlock(&inetdev_lock);
271
		if (omi >= 1 && omi <= 31 && ((1 << omi) & rpf_mask))
272
			rpf = 0;
273
	}
274
	table = FIB_RES_TABLE(&res);
275
	prefixlen = res.prefixlen;
276
	scope = res.scope;
250
	fib_res_put(&res);
277
	fib_res_put(&res);
251
	if (no_addr)
278
	if (no_addr)
252
		goto last_resort;
279
		goto last_resort;
253
	if (rpf)
254
		goto e_inval;
255
	key.oif = dev->ifindex;
280
	key.oif = dev->ifindex;
281
	if (fwdsh)
282
		key.iif = loopback_dev.ifindex;
256
283
257
	ret = 0;
284
	ret = 0;
258
	if (fib_lookup(&key, &res) == 0) {
285
	if (fib_lookup(&key, &res) == 0) {
259
		if (res.type == RTN_UNICAST) {
286
		if (res.type == RTN_UNICAST &&
287
		    ((table == FIB_RES_TABLE(&res) &&
288
		      res.prefixlen >= prefixlen && res.scope >= scope) ||
289
		     !rpf)) {
260
			*spec_dst = FIB_RES_PREFSRC(res);
290
			*spec_dst = FIB_RES_PREFSRC(res);
261
			ret = FIB_RES_NH(res).nh_scope >= RT_SCOPE_HOST;
291
			ret = FIB_RES_NH(res).nh_scope >= RT_SCOPE_HOST;
292
			fib_res_put(&res);
293
			return ret;
262
		}
294
		}
263
		fib_res_put(&res);
295
		fib_res_put(&res);
264
	}
296
	}
297
	if (rpf)
298
		goto e_inval;
265
	return ret;
299
	return ret;
266
300
267
last_resort:
301
last_resort:
Lines 579-587 static int fib_inetaddr_event(struct not Link Here
579
	switch (event) {
613
	switch (event) {
580
	case NETDEV_UP:
614
	case NETDEV_UP:
581
		fib_add_ifaddr(ifa);
615
		fib_add_ifaddr(ifa);
582
#ifdef CONFIG_IP_ROUTE_MULTIPATH
583
		fib_sync_up(ifa->ifa_dev->dev);
616
		fib_sync_up(ifa->ifa_dev->dev);
584
#endif
585
		rt_cache_flush(-1);
617
		rt_cache_flush(-1);
586
		break;
618
		break;
587
	case NETDEV_DOWN:
619
	case NETDEV_DOWN:
Lines 617-625 static int fib_netdev_event(struct notif Link Here
617
		for_ifa(in_dev) {
649
		for_ifa(in_dev) {
618
			fib_add_ifaddr(ifa);
650
			fib_add_ifaddr(ifa);
619
		} endfor_ifa(in_dev);
651
		} endfor_ifa(in_dev);
620
#ifdef CONFIG_IP_ROUTE_MULTIPATH
621
		fib_sync_up(dev);
652
		fib_sync_up(dev);
622
#endif
623
		rt_cache_flush(-1);
653
		rt_cache_flush(-1);
624
		break;
654
		break;
625
	case NETDEV_DOWN:
655
	case NETDEV_DOWN:
(-)linux-2.4.21/net/ipv4/fib_hash.c (-35 / +100 lines)
Lines 71-76 struct fib_node Link Here
71
	struct fib_info		*fn_info;
71
	struct fib_info		*fn_info;
72
#define FIB_INFO(f)	((f)->fn_info)
72
#define FIB_INFO(f)	((f)->fn_info)
73
	fn_key_t		fn_key;
73
	fn_key_t		fn_key;
74
	int			fn_last_dflt;
74
	u8			fn_tos;
75
	u8			fn_tos;
75
	u8			fn_type;
76
	u8			fn_type;
76
	u8			fn_scope;
77
	u8			fn_scope;
Lines 312-383 out: Link Here
312
	return err;
313
	return err;
313
}
314
}
314
315
315
static int fn_hash_last_dflt=-1;
316
static int fib_detect_death(struct fib_info *fi, int order, int last_dflt,
316
317
			    struct fib_info **last_resort, int *last_idx,
317
static int fib_detect_death(struct fib_info *fi, int order,
318
			    int *last_nhsel, const struct rt_key *key)
318
			    struct fib_info **last_resort, int *last_idx)
319
{
319
{
320
	struct neighbour *n;
320
	struct neighbour *n;
321
	int state = NUD_NONE;
321
	int nhsel;
322
	int state;
323
	struct fib_nh * nh;
324
	u32 dst;
325
	int flag, dead = 1;
326
327
	/* change_nexthops(fi) { */
328
	for (nhsel = 0, nh = fi->fib_nh; nhsel < fi->fib_nhs; nh++, nhsel++) {
329
		if (key->oif && key->oif != nh->nh_oif)
330
			continue;
331
		if (key->gw && key->gw != nh->nh_gw && nh->nh_gw &&
332
		    nh->nh_scope == RT_SCOPE_LINK)
333
			continue;
334
		if (nh->nh_flags & RTNH_F_DEAD)
335
			continue;
322
336
323
	n = neigh_lookup(&arp_tbl, &fi->fib_nh[0].nh_gw, fi->fib_dev);
337
		flag = 0;
324
	if (n) {
338
		if (nh->nh_dev->flags & IFF_NOARP) {
325
		state = n->nud_state;
339
			dead = 0;
326
		neigh_release(n);
340
			goto setfl;
341
		}
342
343
		dst = nh->nh_gw;
344
		if (!nh->nh_gw || nh->nh_scope != RT_SCOPE_LINK)
345
			dst = key->dst;
346
347
		state = NUD_NONE;
348
		n = neigh_lookup(&arp_tbl, &dst, nh->nh_dev);
349
		if (n) {
350
			state = n->nud_state;
351
			neigh_release(n);
352
		}
353
		if (state==NUD_REACHABLE ||
354
			((state&NUD_VALID) && order != last_dflt)) {
355
			dead = 0;
356
			goto setfl;
357
		}
358
		if (!(state&NUD_VALID))
359
			flag = 1;
360
		if (!dead)
361
			goto setfl;
362
		if ((state&NUD_VALID) ||
363
		    (*last_idx<0 && order >= last_dflt)) {
364
			*last_resort = fi;
365
			*last_idx = order;
366
			*last_nhsel = nhsel;
367
		}
368
369
		setfl:
370
371
		read_lock_bh(&fib_nhflags_lock);
372
		if (flag)
373
			nh->nh_flags |= RTNH_F_SUSPECT;
374
		else
375
			nh->nh_flags &= ~RTNH_F_SUSPECT;
376
		read_unlock_bh(&fib_nhflags_lock);
327
	}
377
	}
328
	if (state==NUD_REACHABLE)
378
	/* } endfor_nexthops(fi) */
329
		return 0;
379
330
	if ((state&NUD_VALID) && order != fn_hash_last_dflt)
380
	return dead;
331
		return 0;
332
	if ((state&NUD_VALID) ||
333
	    (*last_idx<0 && order > fn_hash_last_dflt)) {
334
		*last_resort = fi;
335
		*last_idx = order;
336
	}
337
	return 1;
338
}
381
}
339
382
340
static void
383
static void
341
fn_hash_select_default(struct fib_table *tb, const struct rt_key *key, struct fib_result *res)
384
fn_hash_select_default(struct fib_table *tb, const struct rt_key *key, struct fib_result *res)
342
{
385
{
343
	int order, last_idx;
386
	int order, last_idx, last_dflt, last_nhsel;
344
	struct fib_node *f;
387
	struct fib_node *f, *first_node;
345
	struct fib_info *fi = NULL;
388
	struct fib_info *fi = NULL;
346
	struct fib_info *last_resort;
389
	struct fib_info *last_resort;
347
	struct fn_hash *t = (struct fn_hash*)tb->tb_data;
390
	struct fn_hash *t = (struct fn_hash*)tb->tb_data;
348
	struct fn_zone *fz = t->fn_zones[0];
391
	struct fn_zone *fz = t->fn_zones[res->prefixlen];
392
	fn_key_t k;
349
393
350
	if (fz == NULL)
394
	if (fz == NULL)
351
		return;
395
		return;
352
396
397
	k = fz_key(key->dst, fz);
398
	last_dflt = -2;
399
	first_node = NULL;
353
	last_idx = -1;
400
	last_idx = -1;
354
	last_resort = NULL;
401
	last_resort = NULL;
402
	last_nhsel = 0;
355
	order = -1;
403
	order = -1;
356
404
357
	read_lock(&fib_hash_lock);
405
	read_lock(&fib_hash_lock);
358
	for (f = fz->fz_hash[0]; f; f = f->fn_next) {
406
	for (f = fz_chain(k, fz); f; f = f->fn_next) {
359
		struct fib_info *next_fi = FIB_INFO(f);
407
		struct fib_info *next_fi = FIB_INFO(f);
360
408
361
		if ((f->fn_state&FN_S_ZOMBIE) ||
409
		if (!fn_key_eq(k, f->fn_key) ||
410
		    (f->fn_state&FN_S_ZOMBIE) ||
362
		    f->fn_scope != res->scope ||
411
		    f->fn_scope != res->scope ||
412
#ifdef CONFIG_IP_ROUTE_TOS
413
		    (f->fn_tos && f->fn_tos != key->tos) ||
414
#endif
363
		    f->fn_type != RTN_UNICAST)
415
		    f->fn_type != RTN_UNICAST)
364
			continue;
416
			continue;
365
417
366
		if (next_fi->fib_priority > res->fi->fib_priority)
418
		if (next_fi->fib_priority > res->fi->fib_priority)
367
			break;
419
			break;
368
		if (!next_fi->fib_nh[0].nh_gw || next_fi->fib_nh[0].nh_scope != RT_SCOPE_LINK)
369
			continue;
370
		f->fn_state |= FN_S_ACCESSED;
420
		f->fn_state |= FN_S_ACCESSED;
371
421
372
		if (fi == NULL) {
422
		if (!first_node) {
373
			if (next_fi != res->fi)
423
			last_dflt = f->fn_last_dflt;
374
				break;
424
			first_node = f;
375
		} else if (!fib_detect_death(fi, order, &last_resort, &last_idx)) {
425
		}
426
		if (fi && !fib_detect_death(fi, order, last_dflt,
427
				&last_resort, &last_idx, &last_nhsel, key)) {
376
			if (res->fi)
428
			if (res->fi)
377
				fib_info_put(res->fi);
429
				fib_info_put(res->fi);
378
			res->fi = fi;
430
			res->fi = fi;
379
			atomic_inc(&fi->fib_clntref);
431
			atomic_inc(&fi->fib_clntref);
380
			fn_hash_last_dflt = order;
432
			first_node->fn_last_dflt = order;
381
			goto out;
433
			goto out;
382
		}
434
		}
383
		fi = next_fi;
435
		fi = next_fi;
Lines 385-400 fn_hash_select_default(struct fib_table Link Here
385
	}
437
	}
386
438
387
	if (order<=0 || fi==NULL) {
439
	if (order<=0 || fi==NULL) {
388
		fn_hash_last_dflt = -1;
440
		if (fi && fi->fib_nhs > 1 &&
441
		    fib_detect_death(fi, order, last_dflt,
442
			&last_resort, &last_idx, &last_nhsel, key) &&
443
		    last_resort == fi) {
444
			read_lock_bh(&fib_nhflags_lock);
445
			fi->fib_nh[last_nhsel].nh_flags &= ~RTNH_F_SUSPECT;
446
			read_unlock_bh(&fib_nhflags_lock);
447
		}
448
		if (first_node) first_node->fn_last_dflt = -1;
389
		goto out;
449
		goto out;
390
	}
450
	}
391
451
392
	if (!fib_detect_death(fi, order, &last_resort, &last_idx)) {
452
	if (!fib_detect_death(fi, order, last_dflt, &last_resort, &last_idx,
453
			      &last_nhsel, key)) {
393
		if (res->fi)
454
		if (res->fi)
394
			fib_info_put(res->fi);
455
			fib_info_put(res->fi);
395
		res->fi = fi;
456
		res->fi = fi;
396
		atomic_inc(&fi->fib_clntref);
457
		atomic_inc(&fi->fib_clntref);
397
		fn_hash_last_dflt = order;
458
		first_node->fn_last_dflt = order;
398
		goto out;
459
		goto out;
399
	}
460
	}
400
461
Lines 404-411 fn_hash_select_default(struct fib_table Link Here
404
		res->fi = last_resort;
465
		res->fi = last_resort;
405
		if (last_resort)
466
		if (last_resort)
406
			atomic_inc(&last_resort->fib_clntref);
467
			atomic_inc(&last_resort->fib_clntref);
468
		read_lock_bh(&fib_nhflags_lock);
469
		last_resort->fib_nh[last_nhsel].nh_flags &= ~RTNH_F_SUSPECT;
470
		read_unlock_bh(&fib_nhflags_lock);
471
		first_node->fn_last_dflt = last_idx;
407
	}
472
	}
408
	fn_hash_last_dflt = last_idx;
409
out:
473
out:
410
	read_unlock(&fib_hash_lock);
474
	read_unlock(&fib_hash_lock);
411
}
475
}
Lines 567-572 replace: Link Here
567
631
568
	memset(new_f, 0, sizeof(struct fib_node));
632
	memset(new_f, 0, sizeof(struct fib_node));
569
633
634
	new_f->fn_last_dflt = -1;
570
	new_f->fn_key = key;
635
	new_f->fn_key = key;
571
#ifdef CONFIG_IP_ROUTE_TOS
636
#ifdef CONFIG_IP_ROUTE_TOS
572
	new_f->fn_tos = tos;
637
	new_f->fn_tos = tos;
(-)linux-2.4.21/net/ipv4/fib_rules.c (-2 / +9 lines)
Lines 307-312 static void fib_rules_attach(struct net_ Link Here
307
	}
307
	}
308
}
308
}
309
309
310
int fib_result_table(struct fib_result *res)
311
{
312
	return res->r->r_table;
313
}
314
310
int fib_lookup(const struct rt_key *key, struct fib_result *res)
315
int fib_lookup(const struct rt_key *key, struct fib_result *res)
311
{
316
{
312
	int err;
317
	int err;
Lines 371-378 FRprintk("FAILURE\n"); Link Here
371
376
372
void fib_select_default(const struct rt_key *key, struct fib_result *res)
377
void fib_select_default(const struct rt_key *key, struct fib_result *res)
373
{
378
{
374
	if (res->r && res->r->r_action == RTN_UNICAST &&
379
	if (res->r &&
375
	    FIB_RES_GW(*res) && FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK) {
380
	    (res->r->r_action == RTN_UNICAST || res->r->r_action == RTN_NAT) &&
381
	    ((FIB_RES_GW(*res) && FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK) ||
382
	     FIB_RES_NH(*res).nh_scope == RT_SCOPE_HOST)) {
376
		struct fib_table *tb;
383
		struct fib_table *tb;
377
		if ((tb = fib_get_table(res->r->r_table)) != NULL)
384
		if ((tb = fib_get_table(res->r->r_table)) != NULL)
378
			tb->tb_select_default(tb, key, res);
385
			tb->tb_select_default(tb, key, res);
(-)linux-2.4.21/net/ipv4/fib_semantics.c (-52 / +164 lines)
Lines 48-53 Link Here
48
static struct fib_info 	*fib_info_list;
48
static struct fib_info 	*fib_info_list;
49
static rwlock_t fib_info_lock = RW_LOCK_UNLOCKED;
49
static rwlock_t fib_info_lock = RW_LOCK_UNLOCKED;
50
int fib_info_cnt;
50
int fib_info_cnt;
51
rwlock_t fib_nhflags_lock = RW_LOCK_UNLOCKED;
51
52
52
#define for_fib_info() { struct fib_info *fi; \
53
#define for_fib_info() { struct fib_info *fi; \
53
	for (fi = fib_info_list; fi; fi = fi->fib_next)
54
	for (fi = fib_info_list; fi; fi = fi->fib_next)
Lines 150-156 static __inline__ int nh_comp(const stru Link Here
150
#ifdef CONFIG_NET_CLS_ROUTE
151
#ifdef CONFIG_NET_CLS_ROUTE
151
		    nh->nh_tclassid != onh->nh_tclassid ||
152
		    nh->nh_tclassid != onh->nh_tclassid ||
152
#endif
153
#endif
153
		    ((nh->nh_flags^onh->nh_flags)&~RTNH_F_DEAD))
154
		    ((nh->nh_flags^onh->nh_flags)&~RTNH_F_BADSTATE))
154
			return -1;
155
			return -1;
155
		onh++;
156
		onh++;
156
	} endfor_nexthops(fi);
157
	} endfor_nexthops(fi);
Lines 166-172 static __inline__ struct fib_info * fib_ Link Here
166
		    nfi->fib_prefsrc == fi->fib_prefsrc &&
167
		    nfi->fib_prefsrc == fi->fib_prefsrc &&
167
		    nfi->fib_priority == fi->fib_priority &&
168
		    nfi->fib_priority == fi->fib_priority &&
168
		    memcmp(nfi->fib_metrics, fi->fib_metrics, sizeof(fi->fib_metrics)) == 0 &&
169
		    memcmp(nfi->fib_metrics, fi->fib_metrics, sizeof(fi->fib_metrics)) == 0 &&
169
		    ((nfi->fib_flags^fi->fib_flags)&~RTNH_F_DEAD) == 0 &&
170
		    ((nfi->fib_flags^fi->fib_flags)&~RTNH_F_BADSTATE) == 0 &&
170
		    (nfi->fib_nhs == 0 || nh_comp(fi, nfi) == 0))
171
		    (nfi->fib_nhs == 0 || nh_comp(fi, nfi) == 0))
171
			return fi;
172
			return fi;
172
	} endfor_fib_info();
173
	} endfor_fib_info();
Lines 365-372 static int fib_check_nh(const struct rtm Link Here
365
				return -EINVAL;
366
				return -EINVAL;
366
			if ((dev = __dev_get_by_index(nh->nh_oif)) == NULL)
367
			if ((dev = __dev_get_by_index(nh->nh_oif)) == NULL)
367
				return -ENODEV;
368
				return -ENODEV;
368
			if (!(dev->flags&IFF_UP))
369
			if (!(dev->flags&IFF_UP)) {
369
				return -ENETDOWN;
370
				if (fi->fib_protocol != RTPROT_STATIC)
371
					return -ENETDOWN;
372
				nh->nh_flags |= RTNH_F_DEAD;
373
			}
370
			nh->nh_dev = dev;
374
			nh->nh_dev = dev;
371
			atomic_inc(&dev->refcnt);
375
			atomic_inc(&dev->refcnt);
372
			nh->nh_scope = RT_SCOPE_LINK;
376
			nh->nh_scope = RT_SCOPE_LINK;
Lines 380-402 static int fib_check_nh(const struct rtm Link Here
380
		/* It is not necessary, but requires a bit of thinking */
384
		/* It is not necessary, but requires a bit of thinking */
381
		if (key.scope < RT_SCOPE_LINK)
385
		if (key.scope < RT_SCOPE_LINK)
382
			key.scope = RT_SCOPE_LINK;
386
			key.scope = RT_SCOPE_LINK;
383
		if ((err = fib_lookup(&key, &res)) != 0)
387
384
			return err;
388
		err = fib_lookup(&key, &res);
385
		err = -EINVAL;
389
		if (err) {
386
		if (res.type != RTN_UNICAST && res.type != RTN_LOCAL)
390
			struct in_device *in_dev;
387
			goto out;
391
388
		nh->nh_scope = res.scope;
392
			if (err != -ENETUNREACH ||
389
		nh->nh_oif = FIB_RES_OIF(res);
393
			    fi->fib_protocol != RTPROT_STATIC)
390
		if ((nh->nh_dev = FIB_RES_DEV(res)) == NULL)
394
				return err;
391
			goto out;
395
392
		atomic_inc(&nh->nh_dev->refcnt);
396
			in_dev = inetdev_by_index(nh->nh_oif);
393
		err = -ENETDOWN;
397
			if (in_dev == NULL ||
394
		if (!(nh->nh_dev->flags & IFF_UP))
398
			    in_dev->dev->flags & IFF_UP) {
395
			goto out;
399
				if (in_dev)
396
		err = 0;
400
					in_dev_put(in_dev);
401
				return err;
402
			}
403
			nh->nh_flags |= RTNH_F_DEAD;
404
			nh->nh_scope = RT_SCOPE_LINK;
405
			nh->nh_dev = in_dev->dev;
406
			atomic_inc(&nh->nh_dev->refcnt);
407
			in_dev_put(in_dev);
408
		} else {
409
			err = -EINVAL;
410
			if (res.type != RTN_UNICAST && res.type != RTN_LOCAL)
411
				goto out;
412
			nh->nh_scope = res.scope;
413
			nh->nh_oif = FIB_RES_OIF(res);
414
			if ((nh->nh_dev = FIB_RES_DEV(res)) == NULL)
415
				goto out;
416
			atomic_inc(&nh->nh_dev->refcnt);
417
			if (!(nh->nh_dev->flags & IFF_UP)) {
418
				if (fi->fib_protocol != RTPROT_STATIC) {
419
					err = -ENETDOWN;
420
					goto out;
421
				}
422
				nh->nh_flags |= RTNH_F_DEAD;
423
			}
424
			err = 0;
397
out:
425
out:
398
		fib_res_put(&res);
426
			fib_res_put(&res);
399
		return err;
427
			return err;
428
		}
400
	} else {
429
	} else {
401
		struct in_device *in_dev;
430
		struct in_device *in_dev;
402
431
Lines 407-414 out: Link Here
407
		if (in_dev == NULL)
436
		if (in_dev == NULL)
408
			return -ENODEV;
437
			return -ENODEV;
409
		if (!(in_dev->dev->flags&IFF_UP)) {
438
		if (!(in_dev->dev->flags&IFF_UP)) {
410
			in_dev_put(in_dev);
439
			if (fi->fib_protocol != RTPROT_STATIC) {
411
			return -ENETDOWN;
440
				in_dev_put(in_dev);
441
				return -ENETDOWN;
442
			}
443
			nh->nh_flags |= RTNH_F_DEAD;
412
		}
444
		}
413
		nh->nh_dev = in_dev->dev;
445
		nh->nh_dev = in_dev->dev;
414
		atomic_inc(&nh->nh_dev->refcnt);
446
		atomic_inc(&nh->nh_dev->refcnt);
Lines 603-610 fib_semantic_match(int type, struct fib_ Link Here
603
			for_nexthops(fi) {
635
			for_nexthops(fi) {
604
				if (nh->nh_flags&RTNH_F_DEAD)
636
				if (nh->nh_flags&RTNH_F_DEAD)
605
					continue;
637
					continue;
606
				if (!key->oif || key->oif == nh->nh_oif)
638
				if (key->oif && key->oif != nh->nh_oif)
607
					break;
639
					continue;
640
				if (key->gw && key->gw != nh->nh_gw &&
641
				    nh->nh_gw && nh->nh_scope == RT_SCOPE_LINK)
642
					continue;
643
				break;
608
			}
644
			}
609
#ifdef CONFIG_IP_ROUTE_MULTIPATH
645
#ifdef CONFIG_IP_ROUTE_MULTIPATH
610
			if (nhsel < fi->fib_nhs) {
646
			if (nhsel < fi->fib_nhs) {
Lines 870-891 int fib_sync_down(u32 local, struct net_ Link Here
870
		if (local && fi->fib_prefsrc == local) {
906
		if (local && fi->fib_prefsrc == local) {
871
			fi->fib_flags |= RTNH_F_DEAD;
907
			fi->fib_flags |= RTNH_F_DEAD;
872
			ret++;
908
			ret++;
873
		} else if (dev && fi->fib_nhs) {
909
		} else if (fi->fib_nhs) {
874
			int dead = 0;
910
			int dead = 0;
875
911
876
			change_nexthops(fi) {
912
			change_nexthops(fi) {
877
				if (nh->nh_flags&RTNH_F_DEAD)
913
				if (nh->nh_flags&RTNH_F_DEAD) {
878
					dead++;
914
					if (fi->fib_protocol!=RTPROT_STATIC ||
879
				else if (nh->nh_dev == dev &&
915
					    nh->nh_dev == NULL ||
880
					 nh->nh_scope != scope) {
916
					    !__in_dev_get(nh->nh_dev) ||
881
					nh->nh_flags |= RTNH_F_DEAD;
917
					    nh->nh_dev->flags&IFF_UP)
918
						dead++;
919
				} else if ((nh->nh_dev == dev && dev &&
920
					    nh->nh_scope != scope) ||
921
					    (local == nh->nh_gw && local &&
922
					     nh->nh_oif)) {
923
					write_lock_bh(&fib_nhflags_lock);
882
#ifdef CONFIG_IP_ROUTE_MULTIPATH
924
#ifdef CONFIG_IP_ROUTE_MULTIPATH
883
					spin_lock_bh(&fib_multipath_lock);
925
					spin_lock(&fib_multipath_lock);
926
					nh->nh_flags |= RTNH_F_DEAD;
884
					fi->fib_power -= nh->nh_power;
927
					fi->fib_power -= nh->nh_power;
885
					nh->nh_power = 0;
928
					nh->nh_power = 0;
886
					spin_unlock_bh(&fib_multipath_lock);
929
					spin_unlock(&fib_multipath_lock);
930
#else
931
					nh->nh_flags |= RTNH_F_DEAD;
887
#endif
932
#endif
888
					dead++;
933
					write_unlock_bh(&fib_nhflags_lock);
934
					if (fi->fib_protocol!=RTPROT_STATIC ||
935
					    force ||
936
					    (dev && __in_dev_get(dev) == NULL))
937
						dead++;
889
				}
938
				}
890
#ifdef CONFIG_IP_ROUTE_MULTIPATH
939
#ifdef CONFIG_IP_ROUTE_MULTIPATH
891
				if (force > 1 && nh->nh_dev == dev) {
940
				if (force > 1 && nh->nh_dev == dev) {
Lines 903-939 int fib_sync_down(u32 local, struct net_ Link Here
903
	return ret;
952
	return ret;
904
}
953
}
905
954
906
#ifdef CONFIG_IP_ROUTE_MULTIPATH
907
908
/*
955
/*
909
   Dead device goes up. We wake up dead nexthops.
956
   Dead device goes up or new address is added. We wake up dead nexthops.
910
   It takes sense only on multipath routes.
911
 */
957
 */
912
958
913
int fib_sync_up(struct net_device *dev)
959
int fib_sync_up(struct net_device *dev)
914
{
960
{
915
	int ret = 0;
961
	struct rt_key key;
962
	struct fib_result res;
963
	int ret, rep;
916
964
965
repeat:
917
	if (!(dev->flags&IFF_UP))
966
	if (!(dev->flags&IFF_UP))
918
		return 0;
967
		return 0;
919
968
969
	ret = 0;
970
	rep = 0;
920
	for_fib_info() {
971
	for_fib_info() {
921
		int alive = 0;
972
		int alive = 0;
922
973
923
		change_nexthops(fi) {
974
		change_nexthops(fi) {
924
			if (!(nh->nh_flags&RTNH_F_DEAD)) {
975
			if (!(nh->nh_flags&RTNH_F_DEAD))
925
				alive++;
926
				continue;
976
				continue;
927
			}
928
			if (nh->nh_dev == NULL || !(nh->nh_dev->flags&IFF_UP))
977
			if (nh->nh_dev == NULL || !(nh->nh_dev->flags&IFF_UP))
929
				continue;
978
				continue;
930
			if (nh->nh_dev != dev || __in_dev_get(dev) == NULL)
979
			if (nh->nh_dev != dev || __in_dev_get(dev) == NULL)
931
				continue;
980
				continue;
981
			if (nh->nh_gw && fi->fib_protocol == RTPROT_STATIC) {
982
				memset(&key, 0, sizeof(key));
983
				key.dst = nh->nh_gw;
984
				key.oif = nh->nh_oif;
985
				key.scope = nh->nh_scope;
986
				if (fib_lookup(&key, &res) != 0)
987
					continue;
988
				if (res.type != RTN_UNICAST &&
989
				    res.type != RTN_LOCAL) {
990
					fib_res_put(&res);
991
					continue;
992
				}
993
				nh->nh_scope = res.scope;
994
				fib_res_put(&res);
995
				rep = 1;
996
			}
932
			alive++;
997
			alive++;
998
#ifdef CONFIG_IP_ROUTE_MULTIPATH
933
			spin_lock_bh(&fib_multipath_lock);
999
			spin_lock_bh(&fib_multipath_lock);
934
			nh->nh_power = 0;
1000
			nh->nh_power = 0;
935
			nh->nh_flags &= ~RTNH_F_DEAD;
1001
			nh->nh_flags &= ~RTNH_F_DEAD;
936
			spin_unlock_bh(&fib_multipath_lock);
1002
			spin_unlock_bh(&fib_multipath_lock);
1003
#endif
937
		} endfor_nexthops(fi)
1004
		} endfor_nexthops(fi)
938
1005
939
		if (alive > 0) {
1006
		if (alive > 0) {
Lines 941-949 int fib_sync_up(struct net_device *dev) Link Here
941
			ret++;
1008
			ret++;
942
		}
1009
		}
943
	} endfor_fib_info();
1010
	} endfor_fib_info();
1011
	if (rep)
1012
		goto repeat;
944
	return ret;
1013
	return ret;
945
}
1014
}
946
1015
1016
#ifdef CONFIG_IP_ROUTE_MULTIPATH
1017
947
/*
1018
/*
948
   The algorithm is suboptimal, but it provides really
1019
   The algorithm is suboptimal, but it provides really
949
   fair weighted route distribution.
1020
   fair weighted route distribution.
Lines 952-975 int fib_sync_up(struct net_device *dev) Link Here
952
void fib_select_multipath(const struct rt_key *key, struct fib_result *res)
1023
void fib_select_multipath(const struct rt_key *key, struct fib_result *res)
953
{
1024
{
954
	struct fib_info *fi = res->fi;
1025
	struct fib_info *fi = res->fi;
955
	int w;
1026
	int w, alive;
956
1027
957
	spin_lock_bh(&fib_multipath_lock);
1028
	spin_lock_bh(&fib_multipath_lock);
1029
	if (key->oif) {
1030
		int sel = -1;
1031
		w = -1;
1032
		change_nexthops(fi) {
1033
			if (key->oif != nh->nh_oif)
1034
				continue;
1035
			if (key->gw && key->gw != nh->nh_gw &&
1036
			    nh->nh_gw && nh->nh_scope == RT_SCOPE_LINK)
1037
				continue;
1038
			if (!(nh->nh_flags&RTNH_F_BADSTATE)) {
1039
				if (nh->nh_power > w) {
1040
					w = nh->nh_power;
1041
					sel = nhsel;
1042
				}
1043
			}
1044
		} endfor_nexthops(fi);
1045
		if (sel >= 0) {
1046
			spin_unlock_bh(&fib_multipath_lock);
1047
			res->nh_sel = sel;
1048
			return;
1049
		}
1050
		goto last_resort;
1051
	}
1052
1053
repeat:
958
	if (fi->fib_power <= 0) {
1054
	if (fi->fib_power <= 0) {
959
		int power = 0;
1055
		int power = 0;
960
		change_nexthops(fi) {
1056
		change_nexthops(fi) {
961
			if (!(nh->nh_flags&RTNH_F_DEAD)) {
1057
			if (!(nh->nh_flags&RTNH_F_BADSTATE)) {
962
				power += nh->nh_weight;
1058
				power += nh->nh_weight;
963
				nh->nh_power = nh->nh_weight;
1059
				nh->nh_power = nh->nh_weight;
964
			}
1060
			}
965
		} endfor_nexthops(fi);
1061
		} endfor_nexthops(fi);
966
		fi->fib_power = power;
1062
		fi->fib_power = power;
967
		if (power <= 0) {
1063
		if (power <= 0)
968
			spin_unlock_bh(&fib_multipath_lock);
1064
			goto last_resort;
969
			/* Race condition: route has just become dead. */
970
			res->nh_sel = 0;
971
			return;
972
		}
973
	}
1065
	}
974
1066
975
1067
Lines 979-998 void fib_select_multipath(const struct r Link Here
979
1071
980
	w = jiffies % fi->fib_power;
1072
	w = jiffies % fi->fib_power;
981
1073
1074
	alive = 0;
982
	change_nexthops(fi) {
1075
	change_nexthops(fi) {
983
		if (!(nh->nh_flags&RTNH_F_DEAD) && nh->nh_power) {
1076
		if (!(nh->nh_flags&RTNH_F_BADSTATE) && nh->nh_power) {
984
			if ((w -= nh->nh_power) <= 0) {
1077
			if ((w -= nh->nh_power) <= 0) {
985
				nh->nh_power--;
1078
				nh->nh_power--;
986
				fi->fib_power--;
1079
				fi->fib_power--;
987
				res->nh_sel = nhsel;
988
				spin_unlock_bh(&fib_multipath_lock);
1080
				spin_unlock_bh(&fib_multipath_lock);
1081
				res->nh_sel = nhsel;
989
				return;
1082
				return;
990
			}
1083
			}
1084
			alive = 1;
1085
		}
1086
	} endfor_nexthops(fi);
1087
	if (alive) {
1088
		fi->fib_power = 0;
1089
		goto repeat;
1090
	}
1091
1092
last_resort:
1093
1094
	for_nexthops(fi) {
1095
		if (!(nh->nh_flags&RTNH_F_DEAD)) {
1096
			if (key->oif && key->oif != nh->nh_oif)
1097
				continue;
1098
			if (key->gw && key->gw != nh->nh_gw &&
1099
			    nh->nh_gw && nh->nh_scope == RT_SCOPE_LINK)
1100
				continue;
1101
			spin_unlock_bh(&fib_multipath_lock);
1102
			res->nh_sel = nhsel;
1103
			return;
991
		}
1104
		}
992
	} endfor_nexthops(fi);
1105
	} endfor_nexthops(fi);
993
1106
994
	/* Race condition: route has just become dead. */
1107
	/* Race condition: route has just become dead. */
995
	res->nh_sel = 0;
996
	spin_unlock_bh(&fib_multipath_lock);
1108
	spin_unlock_bh(&fib_multipath_lock);
997
}
1109
}
998
#endif
1110
#endif
(-)linux-2.4.21/net/ipv4/ip_nat_dumb.c (+1 lines)
Lines 124-129 ip_do_nat(struct sk_buff *skb) Link Here
124
					key.dst = ciph->saddr;
124
					key.dst = ciph->saddr;
125
					key.iif = skb->dev->ifindex;
125
					key.iif = skb->dev->ifindex;
126
					key.oif = 0;
126
					key.oif = 0;
127
					key.gw	= 0;
127
#ifdef CONFIG_IP_ROUTE_TOS
128
#ifdef CONFIG_IP_ROUTE_TOS
128
					key.tos = RT_TOS(ciph->tos);
129
					key.tos = RT_TOS(ciph->tos);
129
#endif
130
#endif
(-)linux-2.4.21/net/ipv4/netfilter/ip_fw_compat_masq.c (-6 / +35 lines)
Lines 40-45 do_masquerade(struct sk_buff **pskb, con Link Here
40
	enum ip_conntrack_info ctinfo;
40
	enum ip_conntrack_info ctinfo;
41
	struct ip_conntrack *ct;
41
	struct ip_conntrack *ct;
42
	unsigned int ret;
42
	unsigned int ret;
43
	struct rtable *rt, *skb_rt;
44
	struct net_device *skb_dev;
45
	__u32 saddr;
46
	int new;
43
47
44
	/* Sorry, only ICMP, TCP and UDP. */
48
	/* Sorry, only ICMP, TCP and UDP. */
45
	if (iph->protocol != IPPROTO_ICMP
49
	if (iph->protocol != IPPROTO_ICMP
Lines 63-84 do_masquerade(struct sk_buff **pskb, con Link Here
63
	}
67
	}
64
68
65
	info = &ct->nat.info;
69
	info = &ct->nat.info;
70
	iph = (*pskb)->nh.iph;
71
	saddr = iph->saddr;
72
	new = 0;
66
73
67
	WRITE_LOCK(&ip_nat_lock);
74
	WRITE_LOCK(&ip_nat_lock);
68
	/* Setup the masquerade, if not already */
75
	/* Setup the masquerade, if not already */
69
	if (!info->initialized) {
76
	if (!info->initialized) {
70
		u_int32_t newsrc;
77
		u_int32_t newsrc;
71
		struct rtable *rt;
72
		struct ip_nat_multi_range range;
78
		struct ip_nat_multi_range range;
73
79
80
		skb_rt = (struct rtable *) (*pskb)->dst;
81
		skb_dev = skb_rt->u.dst.dev;
74
		/* Pass 0 instead of saddr, since it's going to be changed
82
		/* Pass 0 instead of saddr, since it's going to be changed
75
		   anyway. */
83
		   anyway. */
76
		if (ip_route_output(&rt, iph->daddr, 0, 0, 0) != 0) {
84
		if (ip_route_output_lookup(&rt, iph->daddr, 0, RT_TOS(iph->tos),
85
		    skb_dev? skb_dev->ifindex : 0,
86
		    skb_dev? skb_rt->rt_gateway : 0) != 0) {
87
			WRITE_UNLOCK(&ip_nat_lock);
77
			DEBUGP("ipnat_rule_masquerade: Can't reroute.\n");
88
			DEBUGP("ipnat_rule_masquerade: Can't reroute.\n");
78
			return NF_DROP;
89
			return NF_DROP;
79
		}
90
		}
80
		newsrc = inet_select_addr(rt->u.dst.dev, rt->rt_gateway,
91
		newsrc = rt->rt_src;
81
					  RT_SCOPE_UNIVERSE);
82
		ip_rt_put(rt);
92
		ip_rt_put(rt);
83
		range = ((struct ip_nat_multi_range)
93
		range = ((struct ip_nat_multi_range)
84
			 { 1,
94
			 { 1,
Lines 93-104 do_masquerade(struct sk_buff **pskb, con Link Here
93
		}
103
		}
94
104
95
		place_in_hashes(ct, info);
105
		place_in_hashes(ct, info);
96
		info->initialized = 1;
106
		new = info->initialized = 1;
97
	} else
107
	} else
98
		DEBUGP("Masquerading already done on this conn.\n");
108
		DEBUGP("Masquerading already done on this conn.\n");
99
	WRITE_UNLOCK(&ip_nat_lock);
109
	WRITE_UNLOCK(&ip_nat_lock);
100
110
101
	return do_bindings(ct, ctinfo, info, NF_IP_POST_ROUTING, pskb);
111
	ret = do_bindings(ct, ctinfo, info, NF_IP_POST_ROUTING, pskb);
112
	if (ret != NF_ACCEPT || saddr == (*pskb)->nh.iph->saddr || new)
113
		return ret;
114
115
	iph = (*pskb)->nh.iph;
116
	if (ip_route_output(&rt, iph->daddr, iph->saddr, RT_TOS(iph->tos), 0) != 0)
117
		return NF_DROP;
118
	
119
	skb_rt = (struct rtable *) (*pskb)->dst;
120
	skb_dev = skb_rt->u.dst.dev;
121
	if (skb_dev != rt->u.dst.dev || rt->rt_gateway != skb_rt->rt_gateway) {
122
		if (skb_dev != rt->u.dst.dev) {
123
			/* TODO: check the new mtu and reply FRAG_NEEDED */
124
		}
125
		dst_release((*pskb)->dst);
126
		(*pskb)->dst = &rt->u.dst;
127
	} else {
128
		ip_rt_put(rt);
129
	}
130
	return NF_ACCEPT;
102
}
131
}
103
132
104
void
133
void
(-)linux-2.4.21/net/ipv4/netfilter/ip_nat_core.c (+54 lines)
Lines 987-992 icmp_reply_translation(struct sk_buff *s Link Here
987
	return NF_ACCEPT;
987
	return NF_ACCEPT;
988
}
988
}
989
989
990
unsigned int
991
ip_nat_route_input(unsigned int hooknum,
992
		struct sk_buff **pskb,
993
		const struct net_device *in,
994
		const struct net_device *out,
995
		int (*okfn)(struct sk_buff *))
996
{
997
	struct sk_buff *skb = *pskb;
998
	struct iphdr *iph;
999
	struct ip_conntrack *ct;
1000
	enum ip_conntrack_info ctinfo;
1001
	struct ip_nat_info *info;
1002
	enum ip_conntrack_dir dir;
1003
	__u32 saddr;
1004
	int i;
1005
1006
	if (!(ct = ip_conntrack_get(skb, &ctinfo)))
1007
		return NF_ACCEPT;
1008
1009
	info = &ct->nat.info;
1010
	if (!info->initialized)
1011
		return NF_ACCEPT;
1012
1013
	if (skb->dst)
1014
		return NF_ACCEPT;
1015
1016
	if (skb->len < sizeof(struct iphdr))
1017
		return NF_ACCEPT;
1018
1019
	iph = skb->nh.iph;
1020
	saddr = iph->saddr;
1021
	hooknum = NF_IP_POST_ROUTING;
1022
	dir = CTINFO2DIR(ctinfo);
1023
1024
	READ_LOCK(&ip_nat_lock);
1025
	for (i = 0; i < info->num_manips; i++) {
1026
		if (info->manips[i].direction == dir
1027
		    && info->manips[i].hooknum == hooknum
1028
		    && info->manips[i].maniptype == IP_NAT_MANIP_SRC) {
1029
			saddr = info->manips[i].manip.ip;
1030
		}
1031
	}
1032
	READ_UNLOCK(&ip_nat_lock);
1033
1034
	if (saddr == iph->saddr)
1035
		return NF_ACCEPT;
1036
1037
	if (ip_route_input_lookup(skb, iph->daddr, iph->saddr, iph->tos,
1038
	    skb->dev, saddr))
1039
		return NF_DROP;
1040
1041
	return NF_ACCEPT;
1042
}
1043
990
int __init ip_nat_init(void)
1044
int __init ip_nat_init(void)
991
{
1045
{
992
	size_t i;
1046
	size_t i;
(-)linux-2.4.21/net/ipv4/netfilter/ip_nat_standalone.c (-1 / +11 lines)
Lines 226-231 ip_nat_local_fn(unsigned int hooknum, Link Here
226
/* Before packet filtering, change destination */
226
/* Before packet filtering, change destination */
227
static struct nf_hook_ops ip_nat_in_ops
227
static struct nf_hook_ops ip_nat_in_ops
228
= { { NULL, NULL }, ip_nat_fn, PF_INET, NF_IP_PRE_ROUTING, NF_IP_PRI_NAT_DST };
228
= { { NULL, NULL }, ip_nat_fn, PF_INET, NF_IP_PRE_ROUTING, NF_IP_PRI_NAT_DST };
229
/* Before routing, route before mangling */
230
static struct nf_hook_ops ip_nat_inr_ops
231
= { { NULL, NULL }, ip_nat_route_input, PF_INET, NF_IP_PRE_ROUTING, NF_IP_PRI_LAST-1 };
229
/* After packet filtering, change source */
232
/* After packet filtering, change source */
230
static struct nf_hook_ops ip_nat_out_ops
233
static struct nf_hook_ops ip_nat_out_ops
231
= { { NULL, NULL }, ip_nat_out, PF_INET, NF_IP_POST_ROUTING, NF_IP_PRI_NAT_SRC};
234
= { { NULL, NULL }, ip_nat_out, PF_INET, NF_IP_POST_ROUTING, NF_IP_PRI_NAT_SRC};
Lines 309-318 static int init_or_cleanup(int init) Link Here
309
		printk("ip_nat_init: can't register in hook.\n");
312
		printk("ip_nat_init: can't register in hook.\n");
310
		goto cleanup_nat;
313
		goto cleanup_nat;
311
	}
314
	}
315
	ret = nf_register_hook(&ip_nat_inr_ops);
316
	if (ret < 0) {
317
		printk("ip_nat_init: can't register inr hook.\n");
318
		goto cleanup_inops;
319
	}
312
	ret = nf_register_hook(&ip_nat_out_ops);
320
	ret = nf_register_hook(&ip_nat_out_ops);
313
	if (ret < 0) {
321
	if (ret < 0) {
314
		printk("ip_nat_init: can't register out hook.\n");
322
		printk("ip_nat_init: can't register out hook.\n");
315
		goto cleanup_inops;
323
		goto cleanup_inrops;
316
	}
324
	}
317
	ret = nf_register_hook(&ip_nat_local_out_ops);
325
	ret = nf_register_hook(&ip_nat_local_out_ops);
318
	if (ret < 0) {
326
	if (ret < 0) {
Lines 340-345 static int init_or_cleanup(int init) Link Here
340
	nf_unregister_hook(&ip_nat_local_out_ops);
348
	nf_unregister_hook(&ip_nat_local_out_ops);
341
 cleanup_outops:
349
 cleanup_outops:
342
	nf_unregister_hook(&ip_nat_out_ops);
350
	nf_unregister_hook(&ip_nat_out_ops);
351
 cleanup_inrops:
352
	nf_unregister_hook(&ip_nat_inr_ops);
343
 cleanup_inops:
353
 cleanup_inops:
344
	nf_unregister_hook(&ip_nat_in_ops);
354
	nf_unregister_hook(&ip_nat_in_ops);
345
 cleanup_nat:
355
 cleanup_nat:
(-)linux-2.4.21/net/ipv4/netfilter/ipt_MASQUERADE.c (+1 lines)
Lines 88-93 masquerade_target(struct sk_buff **pskb, Link Here
88
	key.src = 0; /* Unknown: that's what we're trying to establish */
88
	key.src = 0; /* Unknown: that's what we're trying to establish */
89
	key.tos = RT_TOS((*pskb)->nh.iph->tos)|RTO_CONN;
89
	key.tos = RT_TOS((*pskb)->nh.iph->tos)|RTO_CONN;
90
	key.oif = out->ifindex;
90
	key.oif = out->ifindex;
91
	key.gw	= ((struct rtable *) (*pskb)->dst)->rt_gateway;
91
#ifdef CONFIG_IP_ROUTE_FWMARK
92
#ifdef CONFIG_IP_ROUTE_FWMARK
92
	key.fwmark = (*pskb)->nfmark;
93
	key.fwmark = (*pskb)->nfmark;
93
#endif
94
#endif
(-)linux-2.4.21/net/ipv4/route.c (-19 / +61 lines)
Lines 860-865 void ip_rt_redirect(u32 old_gw, u32 dadd Link Here
860
860
861
				/* Gateway is different ... */
861
				/* Gateway is different ... */
862
				rt->rt_gateway		= new_gw;
862
				rt->rt_gateway		= new_gw;
863
				if (rt->key.gw) rt->key.gw = new_gw;
863
864
864
				/* Redirect received -> path was valid */
865
				/* Redirect received -> path was valid */
865
				dst_confirm(&rth->u.dst);
866
				dst_confirm(&rth->u.dst);
Lines 1265-1271 static int ip_route_input_mc(struct sk_b Link Here
1265
			goto e_inval;
1266
			goto e_inval;
1266
		spec_dst = inet_select_addr(dev, 0, RT_SCOPE_LINK);
1267
		spec_dst = inet_select_addr(dev, 0, RT_SCOPE_LINK);
1267
	} else if (fib_validate_source(saddr, 0, tos, 0,
1268
	} else if (fib_validate_source(saddr, 0, tos, 0,
1268
					dev, &spec_dst, &itag) < 0)
1269
					dev, &spec_dst, &itag, our) < 0)
1269
		goto e_inval;
1270
		goto e_inval;
1270
1271
1271
	rth = dst_alloc(&ipv4_dst_ops);
1272
	rth = dst_alloc(&ipv4_dst_ops);
Lines 1283-1288 static int ip_route_input_mc(struct sk_b Link Here
1283
	rth->key.fwmark	= skb->nfmark;
1284
	rth->key.fwmark	= skb->nfmark;
1284
#endif
1285
#endif
1285
	rth->key.src	= saddr;
1286
	rth->key.src	= saddr;
1287
	rth->key.lsrc	= 0;
1286
	rth->rt_src	= saddr;
1288
	rth->rt_src	= saddr;
1287
#ifdef CONFIG_IP_ROUTE_NAT
1289
#ifdef CONFIG_IP_ROUTE_NAT
1288
	rth->rt_dst_map	= daddr;
1290
	rth->rt_dst_map	= daddr;
Lines 1296-1301 static int ip_route_input_mc(struct sk_b Link Here
1296
	rth->u.dst.dev	= &loopback_dev;
1298
	rth->u.dst.dev	= &loopback_dev;
1297
	dev_hold(rth->u.dst.dev);
1299
	dev_hold(rth->u.dst.dev);
1298
	rth->key.oif	= 0;
1300
	rth->key.oif	= 0;
1301
	rth->key.gw	= 0;
1299
	rth->rt_gateway	= daddr;
1302
	rth->rt_gateway	= daddr;
1300
	rth->rt_spec_dst= spec_dst;
1303
	rth->rt_spec_dst= spec_dst;
1301
	rth->rt_type	= RTN_MULTICAST;
1304
	rth->rt_type	= RTN_MULTICAST;
Lines 1335-1341 e_inval: Link Here
1335
 */
1338
 */
1336
1339
1337
int ip_route_input_slow(struct sk_buff *skb, u32 daddr, u32 saddr,
1340
int ip_route_input_slow(struct sk_buff *skb, u32 daddr, u32 saddr,
1338
			u8 tos, struct net_device *dev)
1341
			u8 tos, struct net_device *dev, u32 lsrc)
1339
{
1342
{
1340
	struct rt_key	key;
1343
	struct rt_key	key;
1341
	struct fib_result res;
1344
	struct fib_result res;
Lines 1355-1370 int ip_route_input_slow(struct sk_buff * Link Here
1355
		goto out;
1358
		goto out;
1356
1359
1357
	key.dst		= daddr;
1360
	key.dst		= daddr;
1358
	key.src		= saddr;
1361
	key.src		= lsrc? : saddr;
1359
	key.tos		= tos;
1362
	key.tos		= tos;
1360
#ifdef CONFIG_IP_ROUTE_FWMARK
1363
#ifdef CONFIG_IP_ROUTE_FWMARK
1361
	key.fwmark	= skb->nfmark;
1364
	key.fwmark	= skb->nfmark;
1362
#endif
1365
#endif
1363
	key.iif		= dev->ifindex;
1366
	key.iif		= lsrc? loopback_dev.ifindex : dev->ifindex;
1364
	key.oif		= 0;
1367
	key.oif		= 0;
1368
	key.gw		= 0;
1365
	key.scope	= RT_SCOPE_UNIVERSE;
1369
	key.scope	= RT_SCOPE_UNIVERSE;
1366
1370
1367
	hash = rt_hash_code(daddr, saddr ^ (key.iif << 5), tos);
1371
	hash = rt_hash_code(daddr, saddr ^ (dev->ifindex << 5), tos);
1368
1372
1369
	/* Check for the most weird martians, which can be not detected
1373
	/* Check for the most weird martians, which can be not detected
1370
	   by fib_lookup.
1374
	   by fib_lookup.
Lines 1385-1390 int ip_route_input_slow(struct sk_buff * Link Here
1385
	if (BADCLASS(daddr) || ZERONET(daddr) || LOOPBACK(daddr))
1389
	if (BADCLASS(daddr) || ZERONET(daddr) || LOOPBACK(daddr))
1386
		goto martian_destination;
1390
		goto martian_destination;
1387
1391
1392
	if (lsrc) {
1393
		if (MULTICAST(lsrc) || BADCLASS(lsrc) ||
1394
		    ZERONET(lsrc) || LOOPBACK(lsrc))
1395
			goto e_inval;
1396
	}
1397
1388
	/*
1398
	/*
1389
	 *	Now we are ready to route packet.
1399
	 *	Now we are ready to route packet.
1390
	 */
1400
	 */
Lines 1394-1399 int ip_route_input_slow(struct sk_buff * Link Here
1394
		goto no_route;
1404
		goto no_route;
1395
	}
1405
	}
1396
	free_res = 1;
1406
	free_res = 1;
1407
	if (lsrc && res.type != RTN_UNICAST && res.type != RTN_NAT)
1408
		goto e_inval;
1409
	key.iif = dev->ifindex;
1410
	key.src = saddr;
1397
1411
1398
	rt_cache_stat[smp_processor_id()].in_slow_tot++;
1412
	rt_cache_stat[smp_processor_id()].in_slow_tot++;
1399
1413
Lines 1404-1410 int ip_route_input_slow(struct sk_buff * Link Here
1404
1418
1405
	if (1) {
1419
	if (1) {
1406
		u32 src_map = saddr;
1420
		u32 src_map = saddr;
1407
		if (res.r)
1421
		if (res.r && !lsrc)
1408
			src_map = fib_rules_policy(saddr, &res, &flags);
1422
			src_map = fib_rules_policy(saddr, &res, &flags);
1409
1423
1410
		if (res.type == RTN_NAT) {
1424
		if (res.type == RTN_NAT) {
Lines 1429-1435 int ip_route_input_slow(struct sk_buff * Link Here
1429
		int result;
1443
		int result;
1430
		result = fib_validate_source(saddr, daddr, tos,
1444
		result = fib_validate_source(saddr, daddr, tos,
1431
					     loopback_dev.ifindex,
1445
					     loopback_dev.ifindex,
1432
					     dev, &spec_dst, &itag);
1446
					     dev, &spec_dst, &itag, 1);
1433
		if (result < 0)
1447
		if (result < 0)
1434
			goto martian_source;
1448
			goto martian_source;
1435
		if (result)
1449
		if (result)
Lines 1443-1450 int ip_route_input_slow(struct sk_buff * Link Here
1443
	if (res.type != RTN_UNICAST)
1457
	if (res.type != RTN_UNICAST)
1444
		goto martian_destination;
1458
		goto martian_destination;
1445
1459
1460
	fib_select_default(&key, &res);
1446
#ifdef CONFIG_IP_ROUTE_MULTIPATH
1461
#ifdef CONFIG_IP_ROUTE_MULTIPATH
1447
	if (res.fi->fib_nhs > 1 && key.oif == 0)
1462
	if (res.fi->fib_nhs > 1)
1448
		fib_select_multipath(&key, &res);
1463
		fib_select_multipath(&key, &res);
1449
#endif
1464
#endif
1450
	out_dev = in_dev_get(FIB_RES_DEV(res));
1465
	out_dev = in_dev_get(FIB_RES_DEV(res));
Lines 1456-1462 int ip_route_input_slow(struct sk_buff * Link Here
1456
	}
1471
	}
1457
1472
1458
	err = fib_validate_source(saddr, daddr, tos, FIB_RES_OIF(res), dev,
1473
	err = fib_validate_source(saddr, daddr, tos, FIB_RES_OIF(res), dev,
1459
				  &spec_dst, &itag);
1474
				  &spec_dst, &itag, 0);
1460
	if (err < 0)
1475
	if (err < 0)
1461
		goto martian_source;
1476
		goto martian_source;
1462
1477
Lines 1464-1469 int ip_route_input_slow(struct sk_buff * Link Here
1464
		flags |= RTCF_DIRECTSRC;
1479
		flags |= RTCF_DIRECTSRC;
1465
1480
1466
	if (out_dev == in_dev && err && !(flags & (RTCF_NAT | RTCF_MASQ)) &&
1481
	if (out_dev == in_dev && err && !(flags & (RTCF_NAT | RTCF_MASQ)) &&
1482
	    !lsrc &&
1467
	    (IN_DEV_SHARED_MEDIA(out_dev) ||
1483
	    (IN_DEV_SHARED_MEDIA(out_dev) ||
1468
	     inet_addr_onlink(out_dev, saddr, FIB_RES_GW(res))))
1484
	     inet_addr_onlink(out_dev, saddr, FIB_RES_GW(res))))
1469
		flags |= RTCF_DOREDIRECT;
1485
		flags |= RTCF_DOREDIRECT;
Lines 1490-1495 int ip_route_input_slow(struct sk_buff * Link Here
1490
#endif
1506
#endif
1491
	rth->key.src	= saddr;
1507
	rth->key.src	= saddr;
1492
	rth->rt_src	= saddr;
1508
	rth->rt_src	= saddr;
1509
	rth->key.lsrc	= lsrc;
1493
	rth->rt_gateway	= daddr;
1510
	rth->rt_gateway	= daddr;
1494
#ifdef CONFIG_IP_ROUTE_NAT
1511
#ifdef CONFIG_IP_ROUTE_NAT
1495
	rth->rt_src_map	= key.src;
1512
	rth->rt_src_map	= key.src;
Lines 1502-1507 int ip_route_input_slow(struct sk_buff * Link Here
1502
	rth->u.dst.dev	= out_dev->dev;
1519
	rth->u.dst.dev	= out_dev->dev;
1503
	dev_hold(rth->u.dst.dev);
1520
	dev_hold(rth->u.dst.dev);
1504
	rth->key.oif 	= 0;
1521
	rth->key.oif 	= 0;
1522
	rth->key.gw	= 0;
1505
	rth->rt_spec_dst= spec_dst;
1523
	rth->rt_spec_dst= spec_dst;
1506
1524
1507
	rth->u.dst.input = ip_forward;
1525
	rth->u.dst.input = ip_forward;
Lines 1512-1518 int ip_route_input_slow(struct sk_buff * Link Here
1512
	rth->rt_flags = flags;
1530
	rth->rt_flags = flags;
1513
1531
1514
#ifdef CONFIG_NET_FASTROUTE
1532
#ifdef CONFIG_NET_FASTROUTE
1515
	if (netdev_fastroute && !(flags&(RTCF_NAT|RTCF_MASQ|RTCF_DOREDIRECT))) {
1533
	if (netdev_fastroute && !(flags&(RTCF_NAT|RTCF_MASQ|RTCF_DOREDIRECT)) &&
1534
	    !lsrc) {
1516
		struct net_device *odev = rth->u.dst.dev;
1535
		struct net_device *odev = rth->u.dst.dev;
1517
		if (odev != dev &&
1536
		if (odev != dev &&
1518
		    dev->accept_fastpath &&
1537
		    dev->accept_fastpath &&
Lines 1535-1546 out: return err; Link Here
1535
brd_input:
1554
brd_input:
1536
	if (skb->protocol != htons(ETH_P_IP))
1555
	if (skb->protocol != htons(ETH_P_IP))
1537
		goto e_inval;
1556
		goto e_inval;
1557
	if (lsrc)
1558
		goto e_inval;
1538
1559
1539
	if (ZERONET(saddr))
1560
	if (ZERONET(saddr))
1540
		spec_dst = inet_select_addr(dev, 0, RT_SCOPE_LINK);
1561
		spec_dst = inet_select_addr(dev, 0, RT_SCOPE_LINK);
1541
	else {
1562
	else {
1542
		err = fib_validate_source(saddr, 0, tos, 0, dev, &spec_dst,
1563
		err = fib_validate_source(saddr, 0, tos, 0, dev, &spec_dst,
1543
					  &itag);
1564
					  &itag, 1);
1544
		if (err < 0)
1565
		if (err < 0)
1545
			goto martian_source;
1566
			goto martian_source;
1546
		if (err)
1567
		if (err)
Lines 1567-1572 local_input: Link Here
1567
#endif
1588
#endif
1568
	rth->key.src	= saddr;
1589
	rth->key.src	= saddr;
1569
	rth->rt_src	= saddr;
1590
	rth->rt_src	= saddr;
1591
	rth->key.lsrc	= 0;
1570
#ifdef CONFIG_IP_ROUTE_NAT
1592
#ifdef CONFIG_IP_ROUTE_NAT
1571
	rth->rt_dst_map	= key.dst;
1593
	rth->rt_dst_map	= key.dst;
1572
	rth->rt_src_map	= key.src;
1594
	rth->rt_src_map	= key.src;
Lines 1579-1584 local_input: Link Here
1579
	rth->u.dst.dev	= &loopback_dev;
1601
	rth->u.dst.dev	= &loopback_dev;
1580
	dev_hold(rth->u.dst.dev);
1602
	dev_hold(rth->u.dst.dev);
1581
	rth->key.oif 	= 0;
1603
	rth->key.oif 	= 0;
1604
	rth->key.gw	= 0;
1582
	rth->rt_gateway	= daddr;
1605
	rth->rt_gateway	= daddr;
1583
	rth->rt_spec_dst= spec_dst;
1606
	rth->rt_spec_dst= spec_dst;
1584
	rth->u.dst.input= ip_local_deliver;
1607
	rth->u.dst.input= ip_local_deliver;
Lines 1644-1651 martian_source: Link Here
1644
	goto e_inval;
1667
	goto e_inval;
1645
}
1668
}
1646
1669
1647
int ip_route_input(struct sk_buff *skb, u32 daddr, u32 saddr,
1670
static inline int
1648
		   u8 tos, struct net_device *dev)
1671
ip_route_input_cached(struct sk_buff *skb, u32 daddr, u32 saddr,
1672
		      u8 tos, struct net_device *dev, u32 lsrc)
1649
{
1673
{
1650
	struct rtable * rth;
1674
	struct rtable * rth;
1651
	unsigned	hash;
1675
	unsigned	hash;
Lines 1659-1664 int ip_route_input(struct sk_buff *skb, Link Here
1659
		if (rth->key.dst == daddr &&
1683
		if (rth->key.dst == daddr &&
1660
		    rth->key.src == saddr &&
1684
		    rth->key.src == saddr &&
1661
		    rth->key.iif == iif &&
1685
		    rth->key.iif == iif &&
1686
		    rth->key.lsrc == lsrc &&
1662
		    rth->key.oif == 0 &&
1687
		    rth->key.oif == 0 &&
1663
#ifdef CONFIG_IP_ROUTE_FWMARK
1688
#ifdef CONFIG_IP_ROUTE_FWMARK
1664
		    rth->key.fwmark == skb->nfmark &&
1689
		    rth->key.fwmark == skb->nfmark &&
Lines 1705-1713 int ip_route_input(struct sk_buff *skb, Link Here
1705
		read_unlock(&inetdev_lock);
1730
		read_unlock(&inetdev_lock);
1706
		return -EINVAL;
1731
		return -EINVAL;
1707
	}
1732
	}
1708
	return ip_route_input_slow(skb, daddr, saddr, tos, dev);
1733
	return ip_route_input_slow(skb, daddr, saddr, tos, dev, lsrc);
1734
}
1735
1736
int ip_route_input(struct sk_buff *skb, u32 daddr, u32 saddr,
1737
		   u8 tos, struct net_device *dev)
1738
{
1739
	return ip_route_input_cached(skb, daddr, saddr, tos, dev, 0);
1709
}
1740
}
1710
1741
1742
int ip_route_input_lookup(struct sk_buff *skb, u32 daddr, u32 saddr,
1743
			  u8 tos, struct net_device *dev, u32 lsrc)
1744
{
1745
	return ip_route_input_cached(skb, daddr, saddr, tos, dev, lsrc);
1746
}
1747
 
1711
/*
1748
/*
1712
 * Major route resolver routine.
1749
 * Major route resolver routine.
1713
 */
1750
 */
Lines 1730-1735 int ip_route_output_slow(struct rtable * Link Here
1730
	key.tos		= tos & IPTOS_RT_MASK;
1767
	key.tos		= tos & IPTOS_RT_MASK;
1731
	key.iif		= loopback_dev.ifindex;
1768
	key.iif		= loopback_dev.ifindex;
1732
	key.oif		= oldkey->oif;
1769
	key.oif		= oldkey->oif;
1770
	key.gw		= oldkey->gw;
1733
#ifdef CONFIG_IP_ROUTE_FWMARK
1771
#ifdef CONFIG_IP_ROUTE_FWMARK
1734
	key.fwmark	= oldkey->fwmark;
1772
	key.fwmark	= oldkey->fwmark;
1735
#endif
1773
#endif
Lines 1819-1824 int ip_route_output_slow(struct rtable * Link Here
1819
		dev_out = &loopback_dev;
1857
		dev_out = &loopback_dev;
1820
		dev_hold(dev_out);
1858
		dev_hold(dev_out);
1821
		key.oif = loopback_dev.ifindex;
1859
		key.oif = loopback_dev.ifindex;
1860
		key.gw = 0;
1822
		res.type = RTN_LOCAL;
1861
		res.type = RTN_LOCAL;
1823
		flags |= RTCF_LOCAL;
1862
		flags |= RTCF_LOCAL;
1824
		goto make_route;
1863
		goto make_route;
Lines 1826-1832 int ip_route_output_slow(struct rtable * Link Here
1826
1865
1827
	if (fib_lookup(&key, &res)) {
1866
	if (fib_lookup(&key, &res)) {
1828
		res.fi = NULL;
1867
		res.fi = NULL;
1829
		if (oldkey->oif) {
1868
		if (oldkey->oif && dev_out->flags&IFF_UP) {
1830
			/* Apparently, routing tables are wrong. Assume,
1869
			/* Apparently, routing tables are wrong. Assume,
1831
			   that the destination is on link.
1870
			   that the destination is on link.
1832
1871
Lines 1869-1874 int ip_route_output_slow(struct rtable * Link Here
1869
		dev_out = &loopback_dev;
1908
		dev_out = &loopback_dev;
1870
		dev_hold(dev_out);
1909
		dev_hold(dev_out);
1871
		key.oif = dev_out->ifindex;
1910
		key.oif = dev_out->ifindex;
1911
		key.gw = 0;
1872
		if (res.fi)
1912
		if (res.fi)
1873
			fib_info_put(res.fi);
1913
			fib_info_put(res.fi);
1874
		res.fi = NULL;
1914
		res.fi = NULL;
Lines 1876-1888 int ip_route_output_slow(struct rtable * Link Here
1876
		goto make_route;
1916
		goto make_route;
1877
	}
1917
	}
1878
1918
1919
	if (res.type == RTN_UNICAST)
1920
		fib_select_default(&key, &res);
1879
#ifdef CONFIG_IP_ROUTE_MULTIPATH
1921
#ifdef CONFIG_IP_ROUTE_MULTIPATH
1880
	if (res.fi->fib_nhs > 1 && key.oif == 0)
1922
	if (res.fi->fib_nhs > 1)
1881
		fib_select_multipath(&key, &res);
1923
		fib_select_multipath(&key, &res);
1882
	else
1883
#endif
1924
#endif
1884
	if (!res.prefixlen && res.type == RTN_UNICAST && !key.oif)
1885
		fib_select_default(&key, &res);
1886
1925
1887
	if (!key.src)
1926
	if (!key.src)
1888
		key.src = FIB_RES_PREFSRC(res);
1927
		key.src = FIB_RES_PREFSRC(res);
Lines 1940-1946 make_route: Link Here
1940
	rth->key.tos	= tos;
1979
	rth->key.tos	= tos;
1941
	rth->key.src	= oldkey->src;
1980
	rth->key.src	= oldkey->src;
1942
	rth->key.iif	= 0;
1981
	rth->key.iif	= 0;
1982
	rth->key.lsrc	= 0;
1943
	rth->key.oif	= oldkey->oif;
1983
	rth->key.oif	= oldkey->oif;
1984
	rth->key.gw	= oldkey->gw;
1944
#ifdef CONFIG_IP_ROUTE_FWMARK
1985
#ifdef CONFIG_IP_ROUTE_FWMARK
1945
	rth->key.fwmark	= oldkey->fwmark;
1986
	rth->key.fwmark	= oldkey->fwmark;
1946
#endif
1987
#endif
Lines 2019-2024 int ip_route_output_key(struct rtable ** Link Here
2019
		    rth->key.src == key->src &&
2060
		    rth->key.src == key->src &&
2020
		    rth->key.iif == 0 &&
2061
		    rth->key.iif == 0 &&
2021
		    rth->key.oif == key->oif &&
2062
		    rth->key.oif == key->oif &&
2063
		    rth->key.gw == key->gw &&
2022
#ifdef CONFIG_IP_ROUTE_FWMARK
2064
#ifdef CONFIG_IP_ROUTE_FWMARK
2023
		    rth->key.fwmark == key->fwmark &&
2065
		    rth->key.fwmark == key->fwmark &&
2024
#endif
2066
#endif
(-)linux-2.4.21/net/netsyms.c (+1 lines)
Lines 250-255 EXPORT_SYMBOL(inet_register_protosw); Link Here
250
EXPORT_SYMBOL(inet_unregister_protosw);
250
EXPORT_SYMBOL(inet_unregister_protosw);
251
EXPORT_SYMBOL(ip_route_output_key);
251
EXPORT_SYMBOL(ip_route_output_key);
252
EXPORT_SYMBOL(ip_route_input);
252
EXPORT_SYMBOL(ip_route_input);
253
EXPORT_SYMBOL(ip_route_input_lookup);
253
EXPORT_SYMBOL(icmp_send);
254
EXPORT_SYMBOL(icmp_send);
254
EXPORT_SYMBOL(ip_options_compile);
255
EXPORT_SYMBOL(ip_options_compile);
255
EXPORT_SYMBOL(ip_options_undo);
256
EXPORT_SYMBOL(ip_options_undo);

Return to bug 20698