Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
42e8ae0c
Commit
42e8ae0c
authored
Jul 25, 2003
by
David S. Miller
Browse files
Options
Browse Files
Download
Plain Diff
Merge nuts.ninka.net:/home/davem/src/BK/network-2.5
into nuts.ninka.net:/home/davem/src/BK/net-2.5
parents
314635e1
e91d89ce
Changes
44
Hide whitespace changes
Inline
Side-by-side
Showing
44 changed files
with
595 additions
and
374 deletions
+595
-374
MAINTAINERS
MAINTAINERS
+2
-2
drivers/net/tg3.c
drivers/net/tg3.c
+2
-0
drivers/pci/pci.ids
drivers/pci/pci.ids
+1
-0
include/linux/ipv6_route.h
include/linux/ipv6_route.h
+1
-0
include/linux/netfilter_bridge/ebtables.h
include/linux/netfilter_bridge/ebtables.h
+24
-22
include/linux/netfilter_ipv4/ipt_REJECT.h
include/linux/netfilter_ipv4/ipt_REJECT.h
+2
-1
include/linux/pci_ids.h
include/linux/pci_ids.h
+1
-0
include/linux/rtnetlink.h
include/linux/rtnetlink.h
+51
-0
net/atm/lec.c
net/atm/lec.c
+8
-13
net/bridge/br_device.c
net/bridge/br_device.c
+18
-3
net/bridge/br_if.c
net/bridge/br_if.c
+26
-24
net/bridge/br_ioctl.c
net/bridge/br_ioctl.c
+2
-0
net/bridge/br_notify.c
net/bridge/br_notify.c
+4
-16
net/bridge/br_stp.c
net/bridge/br_stp.c
+10
-8
net/bridge/br_stp_if.c
net/bridge/br_stp_if.c
+1
-4
net/bridge/br_stp_timer.c
net/bridge/br_stp_timer.c
+7
-6
net/bridge/netfilter/ebt_arp.c
net/bridge/netfilter/ebt_arp.c
+1
-1
net/bridge/netfilter/ebt_dnat.c
net/bridge/netfilter/ebt_dnat.c
+1
-1
net/bridge/netfilter/ebt_ip.c
net/bridge/netfilter/ebt_ip.c
+1
-1
net/bridge/netfilter/ebt_log.c
net/bridge/netfilter/ebt_log.c
+1
-1
net/bridge/netfilter/ebt_mark.c
net/bridge/netfilter/ebt_mark.c
+1
-1
net/bridge/netfilter/ebt_mark_m.c
net/bridge/netfilter/ebt_mark_m.c
+1
-1
net/bridge/netfilter/ebt_pkttype.c
net/bridge/netfilter/ebt_pkttype.c
+1
-1
net/bridge/netfilter/ebt_redirect.c
net/bridge/netfilter/ebt_redirect.c
+1
-1
net/bridge/netfilter/ebt_snat.c
net/bridge/netfilter/ebt_snat.c
+1
-1
net/bridge/netfilter/ebt_stp.c
net/bridge/netfilter/ebt_stp.c
+1
-1
net/bridge/netfilter/ebt_vlan.c
net/bridge/netfilter/ebt_vlan.c
+2
-2
net/core/filter.c
net/core/filter.c
+2
-3
net/core/net-sysfs.c
net/core/net-sysfs.c
+1
-1
net/core/netfilter.c
net/core/netfilter.c
+43
-47
net/core/pktgen.c
net/core/pktgen.c
+32
-17
net/core/rtnetlink.c
net/core/rtnetlink.c
+12
-3
net/core/sysctl_net_core.c
net/core/sysctl_net_core.c
+1
-1
net/decnet/af_decnet.c
net/decnet/af_decnet.c
+1
-0
net/decnet/dn_dev.c
net/decnet/dn_dev.c
+1
-0
net/decnet/dn_route.c
net/decnet/dn_route.c
+1
-0
net/ipv4/ip_output.c
net/ipv4/ip_output.c
+1
-1
net/ipv4/netfilter/ip_conntrack_core.c
net/ipv4/netfilter/ip_conntrack_core.c
+8
-5
net/ipv4/netfilter/ip_conntrack_irc.c
net/ipv4/netfilter/ip_conntrack_irc.c
+13
-4
net/ipv4/netfilter/ipt_MIRROR.c
net/ipv4/netfilter/ipt_MIRROR.c
+83
-46
net/ipv4/netfilter/ipt_REJECT.c
net/ipv4/netfilter/ipt_REJECT.c
+184
-115
net/ipv4/netfilter/ipt_helper.c
net/ipv4/netfilter/ipt_helper.c
+10
-4
net/ipv6/addrconf.c
net/ipv6/addrconf.c
+12
-12
net/ipv6/route.c
net/ipv6/route.c
+18
-4
No files found.
MAINTAINERS
View file @
42e8ae0c
...
...
@@ -1632,8 +1632,8 @@ L: linux-scsi@vger.kernel.org
S: Maintained
SCTP PROTOCOL
P:
Jon Grimm
M:
jgrimm2
@us.ibm.com
P:
Sridhar Samudrala
M:
sri
@us.ibm.com
L: lksctp-developers@lists.sourceforge.net
S: Supported
...
...
drivers/net/tg3.c
View file @
42e8ae0c
...
...
@@ -148,6 +148,8 @@ static struct pci_device_id tg3_pci_tbl[] __devinitdata = {
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
0UL
},
{
PCI_VENDOR_ID_ALTIMA
,
PCI_DEVICE_ID_ALTIMA_AC1000
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
0UL
},
{
PCI_VENDOR_ID_ALTIMA
,
PCI_DEVICE_ID_ALTIMA_AC1001
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
0UL
},
{
PCI_VENDOR_ID_ALTIMA
,
PCI_DEVICE_ID_ALTIMA_AC9100
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
0UL
},
{
0
,
}
...
...
drivers/pci/pci.ids
View file @
42e8ae0c
...
...
@@ -5832,6 +5832,7 @@
1737 Linksys
173b Altima (nee Broadcom)
03e8 AC1000 Gigabit Ethernet
03e9 AC1001 Gigabit Ethernet
03ea AC9100 Gigabit Ethernet
1743 Peppercon AG
8139 ROL/F-100 Fast Ethernet Adapter with ROL
...
...
include/linux/ipv6_route.h
View file @
42e8ae0c
...
...
@@ -16,6 +16,7 @@
#define RTF_DEFAULT 0x00010000
/* default - learned via ND */
#define RTF_ALLONLINK 0x00020000
/* fallback, no routers on link */
#define RTF_ADDRCONF 0x00040000
/* addrconf route - RA */
#define RTF_PREFIX_RT 0x00080000
/* A prefix only route - RA */
#define RTF_NONEXTHOP 0x00200000
/* route with no nexthop */
#define RTF_EXPIRES 0x00400000
...
...
include/linux/netfilter_bridge/ebtables.h
View file @
42e8ae0c
...
...
@@ -33,6 +33,23 @@ struct ebt_counter
uint64_t
bcnt
;
};
struct
ebt_replace
{
char
name
[
EBT_TABLE_MAXNAMELEN
];
unsigned
int
valid_hooks
;
/* nr of rules in the table */
unsigned
int
nentries
;
/* total size of the entries */
unsigned
int
entries_size
;
/* start of the chains */
struct
ebt_entries
*
hook_entry
[
NF_BR_NUMHOOKS
];
/* nr of counters userspace expects back */
unsigned
int
num_counters
;
/* where the kernel will put the old counters */
struct
ebt_counter
*
counters
;
char
*
entries
;
};
struct
ebt_entries
{
/* this field is always set to zero
* See EBT_ENTRY_OR_ENTRIES.
...
...
@@ -47,7 +64,7 @@ struct ebt_entries {
/* nr. of entries */
unsigned
int
nentries
;
/* entry list */
char
data
[
0
];
char
data
[
0
]
__attribute__
((
aligned
(
__alignof__
(
struct
ebt_replace
))))
;
};
/* used for the bitmask of struct ebt_entry */
...
...
@@ -87,7 +104,7 @@ struct ebt_entry_match
}
u
;
/* size of data */
unsigned
int
match_size
;
unsigned
char
data
[
0
];
unsigned
char
data
[
0
]
__attribute__
((
aligned
(
__alignof__
(
struct
ebt_replace
))))
;
};
struct
ebt_entry_watcher
...
...
@@ -98,7 +115,7 @@ struct ebt_entry_watcher
}
u
;
/* size of data */
unsigned
int
watcher_size
;
unsigned
char
data
[
0
];
unsigned
char
data
[
0
]
__attribute__
((
aligned
(
__alignof__
(
struct
ebt_replace
))))
;
};
struct
ebt_entry_target
...
...
@@ -109,7 +126,7 @@ struct ebt_entry_target
}
u
;
/* size of data */
unsigned
int
target_size
;
unsigned
char
data
[
0
];
unsigned
char
data
[
0
]
__attribute__
((
aligned
(
__alignof__
(
struct
ebt_replace
))))
;
};
#define EBT_STANDARD_TARGET "standard"
...
...
@@ -143,24 +160,7 @@ struct ebt_entry {
unsigned
int
target_offset
;
/* sizeof ebt_entry + matches + watchers + target */
unsigned
int
next_offset
;
unsigned
char
elems
[
0
];
};
struct
ebt_replace
{
char
name
[
EBT_TABLE_MAXNAMELEN
];
unsigned
int
valid_hooks
;
/* nr of rules in the table */
unsigned
int
nentries
;
/* total size of the entries */
unsigned
int
entries_size
;
/* start of the chains */
struct
ebt_entries
*
hook_entry
[
NF_BR_NUMHOOKS
];
/* nr of counters userspace expects back */
unsigned
int
num_counters
;
/* where the kernel will put the old counters */
struct
ebt_counter
*
counters
;
char
*
entries
;
unsigned
char
elems
[
0
]
__attribute__
((
aligned
(
__alignof__
(
struct
ebt_replace
))));
};
/* {g,s}etsockopt numbers */
...
...
@@ -263,6 +263,8 @@ struct ebt_table
struct
module
*
me
;
};
#define EBT_ALIGN(s) (((s) + (__alignof__(struct ebt_replace)-1)) & \
~(__alignof__(struct ebt_replace)-1))
extern
int
ebt_register_table
(
struct
ebt_table
*
table
);
extern
void
ebt_unregister_table
(
struct
ebt_table
*
table
);
extern
int
ebt_register_match
(
struct
ebt_match
*
match
);
...
...
include/linux/netfilter_ipv4/ipt_REJECT.h
View file @
42e8ae0c
...
...
@@ -9,7 +9,8 @@ enum ipt_reject_with {
IPT_ICMP_ECHOREPLY
,
IPT_ICMP_NET_PROHIBITED
,
IPT_ICMP_HOST_PROHIBITED
,
IPT_TCP_RESET
IPT_TCP_RESET
,
IPT_ICMP_ADMIN_PROHIBITED
};
struct
ipt_reject_info
{
...
...
include/linux/pci_ids.h
View file @
42e8ae0c
...
...
@@ -1757,6 +1757,7 @@
#define PCI_VENDOR_ID_ALTIMA 0x173b
#define PCI_DEVICE_ID_ALTIMA_AC1000 0x03e8
#define PCI_DEVICE_ID_ALTIMA_AC1000 0x03e9
#define PCI_DEVICE_ID_ALTIMA_AC9100 0x03ea
#define PCI_VENDOR_ID_SYMPHONY 0x1c1c
...
...
include/linux/rtnetlink.h
View file @
42e8ae0c
...
...
@@ -168,6 +168,7 @@ enum rt_scope_t
#define RTM_F_NOTIFY 0x100
/* Notify user of route change */
#define RTM_F_CLONED 0x200
/* This route is cloned */
#define RTM_F_EQUALIZE 0x400
/* Multipath equalizer: NI */
#define RTM_F_PREFIX 0x800
/* Prefix addresses */
/* Reserved table identifiers */
...
...
@@ -458,6 +459,40 @@ struct ifinfomsg
unsigned
ifi_change
;
/* IFF_* change mask */
};
/* The struct should be in sync with struct net_device_stats */
struct
rtnl_link_stats
{
__u32
rx_packets
;
/* total packets received */
__u32
tx_packets
;
/* total packets transmitted */
__u32
rx_bytes
;
/* total bytes received */
__u32
tx_bytes
;
/* total bytes transmitted */
__u32
rx_errors
;
/* bad packets received */
__u32
tx_errors
;
/* packet transmit problems */
__u32
rx_dropped
;
/* no space in linux buffers */
__u32
tx_dropped
;
/* no space available in linux */
__u32
multicast
;
/* multicast packets received */
__u32
collisions
;
/* detailed rx_errors: */
__u32
rx_length_errors
;
__u32
rx_over_errors
;
/* receiver ring buff overflow */
__u32
rx_crc_errors
;
/* recved pkt with crc error */
__u32
rx_frame_errors
;
/* recv'd frame alignment error */
__u32
rx_fifo_errors
;
/* recv'r fifo overrun */
__u32
rx_missed_errors
;
/* receiver missed packet */
/* detailed tx_errors */
__u32
tx_aborted_errors
;
__u32
tx_carrier_errors
;
__u32
tx_fifo_errors
;
__u32
tx_heartbeat_errors
;
__u32
tx_window_errors
;
/* for cslip etc */
__u32
rx_compressed
;
__u32
tx_compressed
;
};
enum
{
IFLA_UNSPEC
,
...
...
@@ -599,6 +634,22 @@ extern void __rta_fill(struct sk_buff *skb, int attrtype, int attrlen, const voi
({ if (skb_tailroom(skb) < (int)RTA_SPACE(attrlen)) goto rtattr_failure; \
__rta_fill(skb, attrtype, attrlen, data); })
static
inline
struct
rtattr
*
__rta_reserve
(
struct
sk_buff
*
skb
,
int
attrtype
,
int
attrlen
)
{
struct
rtattr
*
rta
;
int
size
=
RTA_LENGTH
(
attrlen
);
rta
=
(
struct
rtattr
*
)
skb_put
(
skb
,
RTA_ALIGN
(
size
));
rta
->
rta_type
=
attrtype
;
rta
->
rta_len
=
size
;
return
rta
;
}
#define __RTA_PUT(skb, attrtype, attrlen) \
({ if (skb_tailroom(skb) < (int)RTA_SPACE(attrlen)) goto rtattr_failure; \
__rta_reserve(skb, attrtype, attrlen); })
extern
void
rtmsg_ifinfo
(
int
type
,
struct
net_device
*
dev
,
unsigned
change
);
extern
struct
semaphore
rtnl_sem
;
...
...
net/atm/lec.c
View file @
42e8ae0c
...
...
@@ -1031,7 +1031,7 @@ static void lane2_associate_ind (struct net_device *dev, u8 *mac_addr,
#define LEC_ARP_REFRESH_INTERVAL (3*HZ)
static
void
lec_arp_check_expire
(
unsigned
long
data
);
static
__inline__
void
lec_arp_expire_arp
(
unsigned
long
data
);
static
void
lec_arp_expire_arp
(
unsigned
long
data
);
void
dump_arp_table
(
struct
lec_priv
*
priv
);
/*
...
...
@@ -1371,7 +1371,7 @@ lec_arp_destroy(struct lec_priv *priv)
struct
lec_arp_table
*
entry
,
*
next
;
int
i
;
del_timer
(
&
priv
->
lec_arp_timer
);
del_timer
_sync
(
&
priv
->
lec_arp_timer
);
/*
* Remove all entries
...
...
@@ -1386,7 +1386,7 @@ lec_arp_destroy(struct lec_priv *priv)
entry
=
priv
->
lec_arp_empty_ones
;
while
(
entry
)
{
next
=
entry
->
next
;
del_timer
(
&
entry
->
timer
);
del_timer
_sync
(
&
entry
->
timer
);
lec_arp_clear_vccs
(
entry
);
kfree
(
entry
);
entry
=
next
;
...
...
@@ -1395,7 +1395,7 @@ lec_arp_destroy(struct lec_priv *priv)
entry
=
priv
->
lec_no_forward
;
while
(
entry
)
{
next
=
entry
->
next
;
del_timer
(
&
entry
->
timer
);
del_timer
_sync
(
&
entry
->
timer
);
lec_arp_clear_vccs
(
entry
);
kfree
(
entry
);
entry
=
next
;
...
...
@@ -1404,7 +1404,7 @@ lec_arp_destroy(struct lec_priv *priv)
entry
=
priv
->
mcast_fwds
;
while
(
entry
)
{
next
=
entry
->
next
;
del_timer
(
&
entry
->
timer
);
/* No timer, LANEv2 7.1.20 and 2.3.5.3 */
lec_arp_clear_vccs
(
entry
);
kfree
(
entry
);
entry
=
next
;
...
...
@@ -1478,8 +1478,6 @@ lec_arp_expire_arp(unsigned long data)
entry
=
(
struct
lec_arp_table
*
)
data
;
del_timer
(
&
entry
->
timer
);
DPRINTK
(
"lec_arp_expire_arp
\n
"
);
if
(
entry
->
status
==
ESI_ARP_PENDING
)
{
if
(
entry
->
no_tries
<=
entry
->
priv
->
max_retry_count
)
{
...
...
@@ -1489,8 +1487,7 @@ lec_arp_expire_arp(unsigned long data)
send_to_lecd
(
entry
->
priv
,
l_arp_xmt
,
entry
->
mac_addr
,
NULL
,
NULL
);
entry
->
no_tries
++
;
}
entry
->
timer
.
expires
=
jiffies
+
(
1
*
HZ
);
add_timer
(
&
entry
->
timer
);
mod_timer
(
&
entry
->
timer
,
jiffies
+
(
1
*
HZ
));
}
}
...
...
@@ -1562,8 +1559,6 @@ lec_arp_check_expire(unsigned long data)
unsigned
long
time_to_check
;
int
i
;
del_timer
(
&
priv
->
lec_arp_timer
);
DPRINTK
(
"lec_arp_check_expire %p,%d
\n
"
,
priv
,
atomic_read
(
&
priv
->
lec_arp_users
));
DPRINTK
(
"expire: eo:%p nf:%p
\n
"
,
priv
->
lec_arp_empty_ones
,
...
...
@@ -1621,8 +1616,8 @@ lec_arp_check_expire(unsigned long data)
}
lec_arp_put
(
priv
);
}
priv
->
lec_arp_timer
.
expires
=
jiffies
+
LEC_ARP_REFRESH_INTERVAL
;
add_timer
(
&
priv
->
lec_arp_timer
);
mod_timer
(
&
priv
->
lec_arp_timer
,
jiffies
+
LEC_ARP_REFRESH_INTERVAL
);
}
/*
* Try to find vcc where mac_address is attached.
...
...
net/bridge/br_device.c
View file @
42e8ae0c
...
...
@@ -110,23 +110,38 @@ static int br_dev_accept_fastpath(struct net_device *dev, struct dst_entry *dst)
return
-
1
;
}
/* convert later to direct kfree */
static
void
br_dev_free
(
struct
net_device
*
dev
)
{
struct
net_bridge
*
br
=
dev
->
priv
;
WARN_ON
(
!
list_empty
(
&
br
->
port_list
));
WARN_ON
(
!
list_empty
(
&
br
->
age_list
));
BUG_ON
(
timer_pending
(
&
br
->
hello_timer
));
BUG_ON
(
timer_pending
(
&
br
->
tcn_timer
));
BUG_ON
(
timer_pending
(
&
br
->
topology_change_timer
));
BUG_ON
(
timer_pending
(
&
br
->
gc_timer
));
kfree
(
dev
);
}
void
br_dev_setup
(
struct
net_device
*
dev
)
{
memset
(
dev
->
dev_addr
,
0
,
ETH_ALEN
);
ether_setup
(
dev
);
dev
->
do_ioctl
=
br_dev_do_ioctl
;
dev
->
get_stats
=
br_dev_get_stats
;
dev
->
hard_start_xmit
=
br_dev_xmit
;
dev
->
open
=
br_dev_open
;
dev
->
set_multicast_list
=
br_dev_set_multicast_list
;
dev
->
destructor
=
(
void
(
*
)(
struct
net_device
*
))
k
free
;
dev
->
destructor
=
br_dev_
free
;
SET_MODULE_OWNER
(
dev
);
dev
->
stop
=
br_dev_stop
;
dev
->
accept_fastpath
=
br_dev_accept_fastpath
;
dev
->
tx_queue_len
=
0
;
dev
->
set_mac_address
=
NULL
;
dev
->
priv_flags
=
IFF_EBRIDGE
;
ether_setup
(
dev
);
}
net/bridge/br_if.c
View file @
42e8ae0c
...
...
@@ -41,6 +41,13 @@ static int br_initial_port_cost(struct net_device *dev)
static
void
destroy_nbp
(
void
*
arg
)
{
struct
net_bridge_port
*
p
=
arg
;
p
->
dev
->
br_port
=
NULL
;
BUG_ON
(
timer_pending
(
&
p
->
message_age_timer
));
BUG_ON
(
timer_pending
(
&
p
->
forward_delay_timer
));
BUG_ON
(
timer_pending
(
&
p
->
hold_timer
));
dev_put
(
p
->
dev
);
kfree
(
p
);
}
...
...
@@ -53,16 +60,19 @@ static void del_nbp(struct net_bridge_port *p)
br_stp_disable_port
(
p
);
dev_set_promiscuity
(
dev
,
-
1
);
dev
->
br_port
=
NULL
;
list_del_rcu
(
&
p
->
list
);
br_fdb_delete_by_port
(
p
->
br
,
p
);
del_timer
(
&
p
->
message_age_timer
);
del_timer
(
&
p
->
forward_delay_timer
);
del_timer
(
&
p
->
hold_timer
);
call_rcu
(
&
p
->
rcu
,
destroy_nbp
,
p
);
}
static
void
del_
ifs
(
struct
net_bridge
*
br
)
static
void
del_
br
(
struct
net_bridge
*
br
)
{
struct
list_head
*
p
,
*
n
;
...
...
@@ -71,6 +81,10 @@ static void del_ifs(struct net_bridge *br)
del_nbp
(
list_entry
(
p
,
struct
net_bridge_port
,
list
));
}
spin_unlock_bh
(
&
br
->
lock
);
del_timer_sync
(
&
br
->
gc_timer
);
unregister_netdevice
(
br
->
dev
);
}
static
struct
net_bridge
*
new_nb
(
const
char
*
name
)
...
...
@@ -182,15 +196,14 @@ int br_del_bridge(const char *name)
ret
=
-
EBUSY
;
}
else
{
del_ifs
((
struct
net_bridge
*
)
dev
->
priv
);
unregister_netdevice
(
dev
);
}
else
del_br
(
dev
->
priv
);
rtnl_unlock
();
return
ret
;
}
/* called under bridge lock */
int
br_add_if
(
struct
net_bridge
*
br
,
struct
net_device
*
dev
)
{
struct
net_bridge_port
*
p
;
...
...
@@ -205,7 +218,6 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
return
-
ELOOP
;
dev_hold
(
dev
);
spin_lock_bh
(
&
br
->
lock
);
if
((
p
=
new_nbp
(
br
,
dev
))
==
NULL
)
{
spin_unlock_bh
(
&
br
->
lock
);
dev_put
(
dev
);
...
...
@@ -218,26 +230,21 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
br_fdb_insert
(
br
,
p
,
dev
->
dev_addr
,
1
);
if
((
br
->
dev
->
flags
&
IFF_UP
)
&&
(
dev
->
flags
&
IFF_UP
))
br_stp_enable_port
(
p
);
spin_unlock_bh
(
&
br
->
lock
);
return
0
;
}
/* called under bridge lock */
int
br_del_if
(
struct
net_bridge
*
br
,
struct
net_device
*
dev
)
{
struct
net_bridge_port
*
p
;
int
retval
=
0
;
spin_lock_bh
(
&
br
->
lock
);
if
((
p
=
dev
->
br_port
)
==
NULL
||
p
->
br
!=
br
)
retval
=
-
EINVAL
;
else
{
del_nbp
(
p
);
br_stp_recalculate_bridge_id
(
br
);
}
spin_unlock_bh
(
&
br
->
lock
);
return
-
EINVAL
;
return
retval
;
del_nbp
(
p
);
br_stp_recalculate_bridge_id
(
br
);
return
0
;
}
int
br_get_bridge_ifindices
(
int
*
indices
,
int
num
)
...
...
@@ -274,13 +281,8 @@ void __exit br_cleanup_bridges(void)
rtnl_lock
();
for
(
dev
=
dev_base
;
dev
;
dev
=
nxt
)
{
nxt
=
dev
->
next
;
if
(
dev
->
priv_flags
&
IFF_EBRIDGE
)
{
pr_debug
(
"cleanup %s
\n
"
,
dev
->
name
);
del_ifs
((
struct
net_bridge
*
)
dev
->
priv
);
unregister_netdevice
(
dev
);
}
if
(
dev
->
priv_flags
&
IFF_EBRIDGE
)
del_br
(
dev
->
priv
);
}
rtnl_unlock
();
...
...
net/bridge/br_ioctl.c
View file @
42e8ae0c
...
...
@@ -59,10 +59,12 @@ static int br_ioctl_device(struct net_bridge *br,
if
(
dev
==
NULL
)
return
-
EINVAL
;
spin_lock_bh
(
&
br
->
lock
);
if
(
cmd
==
BRCTL_ADD_IF
)
ret
=
br_add_if
(
br
,
dev
);
else
ret
=
br_del_if
(
br
,
dev
);
spin_unlock_bh
(
&
br
->
lock
);
dev_put
(
dev
);
return
ret
;
...
...
net/bridge/br_notify.c
View file @
42e8ae0c
...
...
@@ -38,39 +38,27 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v
br
=
p
->
br
;
spin_lock_bh
(
&
br
->
lock
);
switch
(
event
)
{
case
NETDEV_CHANGEADDR
:
spin_lock_bh
(
&
br
->
lock
);
br_fdb_changeaddr
(
p
,
dev
->
dev_addr
);
br_stp_recalculate_bridge_id
(
br
);
spin_unlock_bh
(
&
br
->
lock
);
break
;
case
NETDEV_GOING_DOWN
:
/* extend the protocol to send some kind of notification? */
break
;
case
NETDEV_DOWN
:
if
(
br
->
dev
->
flags
&
IFF_UP
)
{
spin_lock_bh
(
&
br
->
lock
);
br_stp_disable_port
(
p
);
spin_unlock_bh
(
&
br
->
lock
);
}
br_stp_disable_port
(
p
);
break
;
case
NETDEV_UP
:
if
(
!
(
br
->
dev
->
flags
&
IFF_UP
))
{
spin_lock_bh
(
&
br
->
lock
);
br_stp_enable_port
(
p
);
spin_unlock_bh
(
&
br
->
lock
);
}
br_stp_enable_port
(
p
);
break
;
case
NETDEV_UNREGISTER
:
br_del_if
(
br
,
dev
);
break
;
}
spin_unlock_bh
(
&
br
->
lock
);
return
NOTIFY_DONE
;
}
net/bridge/br_stp.c
View file @
42e8ae0c
...
...
@@ -20,7 +20,11 @@
#include "br_private_stp.h"
static
const
char
*
br_port_state_names
[]
=
{
"disabled"
,
"learning"
,
"forwarding"
,
"blocking"
,
[
BR_STATE_DISABLED
]
=
"disabled"
,
[
BR_STATE_LISTENING
]
=
"listening"
,
[
BR_STATE_LEARNING
]
=
"learning"
,
[
BR_STATE_FORWARDING
]
=
"forwarding"
,
[
BR_STATE_BLOCKING
]
=
"blocking"
,
};
void
br_log_state
(
const
struct
net_bridge_port
*
p
)
...
...
@@ -289,22 +293,20 @@ static inline void br_topology_change_acknowledged(struct net_bridge *br)
/* called under bridge lock */
void
br_topology_change_detection
(
struct
net_bridge
*
br
)
{
if
(
!
(
br
->
dev
->
flags
&
IFF_UP
))
return
;
int
isroot
=
br_is_root_bridge
(
br
);
pr_info
(
"%s: topology change detected, %s
\n
"
,
br
->
dev
->
name
,
isroot
?
"propgating"
:
"sending tcn bpdu"
);
pr_info
(
"%s: topology change detected"
,
br
->
dev
->
name
);
if
(
br_is_root_bridge
(
br
))
{
printk
(
", propagating"
);
if
(
isroot
)
{
br
->
topology_change
=
1
;
mod_timer
(
&
br
->
topology_change_timer
,
jiffies
+
br
->
bridge_forward_delay
+
br
->
bridge_max_age
);
}
else
if
(
!
br
->
topology_change_detected
)
{
printk
(
", sending tcn bpdu"
);
br_transmit_tcn
(
br
);
mod_timer
(
&
br
->
tcn_timer
,
jiffies
+
br
->
bridge_hello_time
);
}
printk
(
"
\n
"
);
br
->
topology_change_detected
=
1
;
}
...
...
net/bridge/br_stp_if.c
View file @
42e8ae0c
...
...
@@ -43,8 +43,7 @@ void br_stp_enable_bridge(struct net_bridge *br)
struct
net_bridge_port
*
p
;
spin_lock_bh
(
&
br
->
lock
);
br
->
hello_timer
.
expires
=
jiffies
+
br
->
hello_time
;
add_timer
(
&
br
->
hello_timer
);
mod_timer
(
&
br
->
hello_timer
,
jiffies
+
br
->
hello_time
);
br_config_bpdu_generation
(
br
);
list_for_each_entry
(
p
,
&
br
->
port_list
,
list
)
{
...
...
@@ -74,8 +73,6 @@ void br_stp_disable_bridge(struct net_bridge *br)
del_timer_sync
(
&
br
->
hello_timer
);
del_timer_sync
(
&
br
->
topology_change_timer
);
del_timer_sync
(
&
br
->
tcn_timer
);
del_timer_sync
(
&
br
->
gc_timer
);
}
/* called under bridge lock */
...
...
net/bridge/br_stp_timer.c
View file @
42e8ae0c
...
...
@@ -43,8 +43,7 @@ static void br_hello_timer_expired(unsigned long arg)
if
(
br
->
dev
->
flags
&
IFF_UP
)
{
br_config_bpdu_generation
(
br
);
br
->
hello_timer
.
expires
=
jiffies
+
br
->
hello_time
;
add_timer
(
&
br
->
hello_timer
);
mod_timer
(
&
br
->
hello_timer
,
jiffies
+
br
->
hello_time
);
}
spin_unlock_bh
(
&
br
->
lock
);
}
...
...
@@ -73,6 +72,8 @@ static void br_message_age_timer_expired(unsigned long arg)
* check is redundant. I'm leaving it in for now, though.
*/
spin_lock_bh
(
&
br
->
lock
);
if
(
p
->
state
==
BR_STATE_DISABLED
)
goto
unlock
;
was_root
=
br_is_root_bridge
(
br
);
br_become_designated_port
(
p
);
...
...
@@ -80,6 +81,7 @@ static void br_message_age_timer_expired(unsigned long arg)
br_port_state_selection
(
br
);
if
(
br_is_root_bridge
(
br
)
&&
!
was_root
)
br_become_root_bridge
(
br
);
unlock:
spin_unlock_bh
(
&
br
->
lock
);
}
...
...
@@ -93,8 +95,8 @@ static void br_forward_delay_timer_expired(unsigned long arg)
spin_lock_bh
(
&
br
->
lock
);
if
(
p
->
state
==
BR_STATE_LISTENING
)
{
p
->
state
=
BR_STATE_LEARNING
;
p
->
forward_delay_timer
.
expires
=
jiffies
+
br
->
forward_delay
;
add_timer
(
&
p
->
forward_delay_timer
);
mod_timer
(
&
p
->
forward_delay_timer
,
jiffies
+
br
->
forward_delay
);
}
else
if
(
p
->
state
==
BR_STATE_LEARNING
)
{
p
->
state
=
BR_STATE_FORWARDING
;
if
(
br_is_designated_for_some_port
(
br
))
...
...
@@ -113,8 +115,7 @@ static void br_tcn_timer_expired(unsigned long arg)
if
(
br
->
dev
->
flags
&
IFF_UP
)
{
br_transmit_tcn
(
br
);
br
->
tcn_timer
.
expires
=
jiffies
+
br
->
bridge_hello_time
;
add_timer
(
&
br
->
tcn_timer
);
mod_timer
(
&
br
->
tcn_timer
,
jiffies
+
br
->
bridge_hello_time
);
}
spin_unlock_bh
(
&
br
->
lock
);
}
...
...
net/bridge/netfilter/ebt_arp.c
View file @
42e8ae0c
...
...
@@ -99,7 +99,7 @@ static int ebt_arp_check(const char *tablename, unsigned int hookmask,
{
struct
ebt_arp_info
*
info
=
(
struct
ebt_arp_info
*
)
data
;
if
(
datalen
!=
sizeof
(
struct
ebt_arp_info
))
if
(
datalen
!=
EBT_ALIGN
(
sizeof
(
struct
ebt_arp_info
)
))
return
-
EINVAL
;
if
((
e
->
ethproto
!=
__constant_htons
(
ETH_P_ARP
)
&&
e
->
ethproto
!=
__constant_htons
(
ETH_P_RARP
))
||
...
...
net/bridge/netfilter/ebt_dnat.c
View file @
42e8ae0c
...
...
@@ -47,7 +47,7 @@ static int ebt_target_dnat_check(const char *tablename, unsigned int hookmask,
(
hookmask
&
~
((
1
<<
NF_BR_PRE_ROUTING
)
|
(
1
<<
NF_BR_LOCAL_OUT
))))
&&
(
strcmp
(
tablename
,
"broute"
)
||
hookmask
&
~
(
1
<<
NF_BR_BROUTING
))
)
return
-
EINVAL
;
if
(
datalen
!=
sizeof
(
struct
ebt_nat_info
))
if
(
datalen
!=
EBT_ALIGN
(
sizeof
(
struct
ebt_nat_info
)
))
return
-
EINVAL
;
if
(
INVALID_TARGET
)
return
-
EINVAL
;
...
...
net/bridge/netfilter/ebt_ip.c
View file @
42e8ae0c
...
...
@@ -75,7 +75,7 @@ static int ebt_ip_check(const char *tablename, unsigned int hookmask,
{
struct
ebt_ip_info
*
info
=
(
struct
ebt_ip_info
*
)
data
;
if
(
datalen
!=
sizeof
(
struct
ebt_ip_info
))
if
(
datalen
!=
EBT_ALIGN
(
sizeof
(
struct
ebt_ip_info
)
))
return
-
EINVAL
;
if
(
e
->
ethproto
!=
__constant_htons
(
ETH_P_IP
)
||
e
->
invflags
&
EBT_IPROTO
)
...
...
net/bridge/netfilter/ebt_log.c
View file @
42e8ae0c
...
...
@@ -22,7 +22,7 @@ static int ebt_log_check(const char *tablename, unsigned int hookmask,
{
struct
ebt_log_info
*
info
=
(
struct
ebt_log_info
*
)
data
;
if
(
datalen
!=
sizeof
(
struct
ebt_log_info
))
if
(
datalen
!=
EBT_ALIGN
(
sizeof
(
struct
ebt_log_info
)
))
return
-
EINVAL
;
if
(
info
->
bitmask
&
~
EBT_LOG_MASK
)
return
-
EINVAL
;
...
...
net/bridge/netfilter/ebt_mark.c
View file @
42e8ae0c
...
...
@@ -35,7 +35,7 @@ static int ebt_target_mark_check(const char *tablename, unsigned int hookmask,
{
struct
ebt_mark_t_info
*
info
=
(
struct
ebt_mark_t_info
*
)
data
;
if
(
datalen
!=
sizeof
(
struct
ebt_mark_t_info
))
if
(
datalen
!=
EBT_ALIGN
(
sizeof
(
struct
ebt_mark_t_info
)
))
return
-
EINVAL
;
if
(
BASE_CHAIN
&&
info
->
target
==
EBT_RETURN
)
return
-
EINVAL
;
...
...
net/bridge/netfilter/ebt_mark_m.c
View file @
42e8ae0c
...
...
@@ -28,7 +28,7 @@ static int ebt_mark_check(const char *tablename, unsigned int hookmask,
{
struct
ebt_mark_m_info
*
info
=
(
struct
ebt_mark_m_info
*
)
data
;
if
(
datalen
!=
sizeof
(
struct
ebt_mark_m_info
))
if
(
datalen
!=
EBT_ALIGN
(
sizeof
(
struct
ebt_mark_m_info
)
))
return
-
EINVAL
;
if
(
info
->
bitmask
&
~
EBT_MARK_MASK
)
return
-
EINVAL
;
...
...
net/bridge/netfilter/ebt_pkttype.c
View file @
42e8ae0c
...
...
@@ -28,7 +28,7 @@ static int ebt_pkttype_check(const char *tablename, unsigned int hookmask,
{
struct
ebt_pkttype_info
*
info
=
(
struct
ebt_pkttype_info
*
)
data
;
if
(
datalen
!=
sizeof
(
struct
ebt_pkttype_info
))
if
(
datalen
!=
EBT_ALIGN
(
sizeof
(
struct
ebt_pkttype_info
)
))
return
-
EINVAL
;
if
(
info
->
invert
!=
0
&&
info
->
invert
!=
1
)
return
-
EINVAL
;
...
...
net/bridge/netfilter/ebt_redirect.c
View file @
42e8ae0c
...
...
@@ -47,7 +47,7 @@ static int ebt_target_redirect_check(const char *tablename, unsigned int hookmas
{
struct
ebt_redirect_info
*
info
=
(
struct
ebt_redirect_info
*
)
data
;
if
(
datalen
!=
sizeof
(
struct
ebt_redirect_info
))
if
(
datalen
!=
EBT_ALIGN
(
sizeof
(
struct
ebt_redirect_info
)
))
return
-
EINVAL
;
if
(
BASE_CHAIN
&&
info
->
target
==
EBT_RETURN
)
return
-
EINVAL
;
...
...
net/bridge/netfilter/ebt_snat.c
View file @
42e8ae0c
...
...
@@ -40,7 +40,7 @@ static int ebt_target_snat_check(const char *tablename, unsigned int hookmask,
{
struct
ebt_nat_info
*
info
=
(
struct
ebt_nat_info
*
)
data
;
if
(
datalen
!=
sizeof
(
struct
ebt_nat_info
))
if
(
datalen
!=
EBT_ALIGN
(
sizeof
(
struct
ebt_nat_info
)
))
return
-
EINVAL
;
if
(
BASE_CHAIN
&&
info
->
target
==
EBT_RETURN
)
return
-
EINVAL
;
...
...
net/bridge/netfilter/ebt_stp.c
View file @
42e8ae0c
...
...
@@ -150,7 +150,7 @@ static int ebt_stp_check(const char *tablename, unsigned int hookmask,
const
struct
ebt_entry
*
e
,
void
*
data
,
unsigned
int
datalen
)
{
struct
ebt_stp_info
*
info
=
(
struct
ebt_stp_info
*
)
data
;
int
len
=
sizeof
(
struct
ebt_stp_info
);
int
len
=
EBT_ALIGN
(
sizeof
(
struct
ebt_stp_info
)
);
uint8_t
bridge_ula
[
6
]
=
{
0x01
,
0x80
,
0xc2
,
0x00
,
0x00
,
0x00
};
uint8_t
msk
[
6
]
=
{
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
};
...
...
net/bridge/netfilter/ebt_vlan.c
View file @
42e8ae0c
...
...
@@ -35,7 +35,7 @@ MODULE_DESCRIPTION("802.1Q match module (ebtables extension), v"
MODULE_LICENSE
(
"GPL"
);
#define DEBUG_MSG(
...) if (debug) printk (KERN_DEBUG "ebt_vlan: " __VA_ARGS__
)
#define DEBUG_MSG(
args...) if (debug) printk (KERN_DEBUG "ebt_vlan: " args
)
#define INV_FLAG(_inv_flag_) (info->invflags & _inv_flag_) ? "!" : ""
#define GET_BITMASK(_BIT_MASK_) info->bitmask & _BIT_MASK_
#define SET_BITMASK(_BIT_MASK_) info->bitmask |= _BIT_MASK_
...
...
@@ -94,7 +94,7 @@ ebt_check_vlan(const char *tablename,
struct
ebt_vlan_info
*
info
=
(
struct
ebt_vlan_info
*
)
data
;
/* Parameters buffer overflow check */
if
(
datalen
!=
sizeof
(
struct
ebt_vlan_info
))
{
if
(
datalen
!=
EBT_ALIGN
(
sizeof
(
struct
ebt_vlan_info
)
))
{
DEBUG_MSG
(
"passed size %d is not eq to ebt_vlan_info (%Zd)
\n
"
,
datalen
,
sizeof
(
struct
ebt_vlan_info
));
...
...
net/core/filter.c
View file @
42e8ae0c
...
...
@@ -256,10 +256,9 @@ int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen)
k
=
X
+
fentry
->
k
;
goto
load_b
;
case
BPF_LDX
|
BPF_B
|
BPF_MSH
:
k
=
fentry
->
k
;
if
(
k
>=
0
&&
(
unsigned
int
)
k
>=
len
)
if
(
fentry
->
k
>=
len
)
return
0
;
X
=
(
data
[
k
]
&
0xf
)
<<
2
;
X
=
(
data
[
fentry
->
k
]
&
0xf
)
<<
2
;
continue
;
case
BPF_LD
|
BPF_IMM
:
A
=
fentry
->
k
;
...
...
net/core/net-sysfs.c
View file @
42e8ae0c
...
...
@@ -186,7 +186,7 @@ struct netstat_fs_entry {
static
ssize_t
net_device_stat_show
(
unsigned
long
var
,
char
*
buf
)
{
return
sprintf
(
buf
,
"%l
d
\n
"
,
var
);
return
sprintf
(
buf
,
"%l
u
\n
"
,
var
);
}
/* generate a read-only statistics attribute */
...
...
net/core/netfilter.c
View file @
42e8ae0c
...
...
@@ -625,66 +625,62 @@ int ip_route_me_harder(struct sk_buff **pskb)
{
struct
iphdr
*
iph
=
(
*
pskb
)
->
nh
.
iph
;
struct
rtable
*
rt
;
struct
flowi
fl
=
{
.
nl_u
=
{
.
ip4_u
=
{
.
daddr
=
iph
->
daddr
,
.
saddr
=
iph
->
saddr
,
.
tos
=
RT_TOS
(
iph
->
tos
)
|
RTO_CONN
,
#ifdef CONFIG_IP_ROUTE_FWMARK
.
fwmark
=
(
*
pskb
)
->
nfmark
#endif
}
},
.
oif
=
(
*
pskb
)
->
sk
?
(
*
pskb
)
->
sk
->
sk_bound_dev_if
:
0
,
};
struct
net_device
*
dev_src
=
NULL
;
int
err
;
/* accommodate ip_route_output_slow(), which expects the key src to be
0 or a local address; however some non-standard hacks like
ipt_REJECT.c:send_reset() can cause packets with foreign
saddr to be appear on the NF_IP_LOCAL_OUT hook -MB */
if
(
fl
.
fl4_src
&&
!
(
dev_src
=
ip_dev_find
(
fl
.
fl4_src
)))
fl
.
fl4_src
=
0
;
if
((
err
=
ip_route_output_key
(
&
rt
,
&
fl
))
!=
0
)
{
printk
(
"route_me_harder: ip_route_output_key(dst=%u.%u.%u.%u, src=%u.%u.%u.%u, oif=%d, tos=0x%x, fwmark=0x%lx) error %d
\n
"
,
NIPQUAD
(
iph
->
daddr
),
NIPQUAD
(
iph
->
saddr
),
(
*
pskb
)
->
sk
?
(
*
pskb
)
->
sk
->
sk_bound_dev_if
:
0
,
RT_TOS
(
iph
->
tos
)
|
RTO_CONN
,
struct
flowi
fl
=
{};
struct
dst_entry
*
odst
;
unsigned
int
hh_len
;
/* some non-standard hacks like ipt_REJECT.c:send_reset() can cause
* packets with foreign saddr to appear on the NF_IP_LOCAL_OUT hook.
*/
if
(
inet_addr_type
(
iph
->
saddr
)
==
RTN_LOCAL
)
{
fl
.
nl_u
.
ip4_u
.
daddr
=
iph
->
daddr
;
fl
.
nl_u
.
ip4_u
.
saddr
=
iph
->
saddr
;
fl
.
nl_u
.
ip4_u
.
tos
=
RT_TOS
(
iph
->
tos
);
fl
.
oif
=
(
*
pskb
)
->
sk
?
(
*
pskb
)
->
sk
->
sk_bound_dev_if
:
0
;
#ifdef CONFIG_IP_ROUTE_FWMARK
(
*
pskb
)
->
nfmark
,
#else
0UL
,
fl
.
nl_u
.
ip4_u
.
fwmark
=
(
*
pskb
)
->
nfmark
;
#endif
err
);
goto
out
;
}
if
(
ip_route_output_key
(
&
rt
,
&
fl
)
!=
0
)
return
-
1
;
/* Drop old route. */
dst_release
((
*
pskb
)
->
dst
);
(
*
pskb
)
->
dst
=
&
rt
->
u
.
dst
;
/* Drop old route. */
dst_release
((
*
pskb
)
->
dst
);
(
*
pskb
)
->
dst
=
&
rt
->
u
.
dst
;
}
else
{
/* non-local src, find valid iif to satisfy
* rp-filter when calling ip_route_input. */
fl
.
nl_u
.
ip4_u
.
daddr
=
iph
->
saddr
;
if
(
ip_route_output_key
(
&
rt
,
&
fl
)
!=
0
)
return
-
1
;
odst
=
(
*
pskb
)
->
dst
;
if
(
ip_route_input
(
*
pskb
,
iph
->
daddr
,
iph
->
saddr
,
RT_TOS
(
iph
->
tos
),
rt
->
u
.
dst
.
dev
)
!=
0
)
{
dst_release
(
&
rt
->
u
.
dst
);
return
-
1
;
}
dst_release
(
&
rt
->
u
.
dst
);
dst_release
(
odst
);
}
if
((
*
pskb
)
->
dst
->
error
)
return
-
1
;
/* Change in oif may mean change in hh_len. */
if
(
skb_headroom
(
*
pskb
)
<
(
*
pskb
)
->
dst
->
dev
->
hard_header_len
)
{
hh_len
=
(
*
pskb
)
->
dst
->
dev
->
hard_header_len
;
if
(
skb_headroom
(
*
pskb
)
<
hh_len
)
{
struct
sk_buff
*
nskb
;
nskb
=
skb_realloc_headroom
(
*
pskb
,
(
*
pskb
)
->
dst
->
dev
->
hard_header_len
);
if
(
!
nskb
)
{
err
=
-
ENOMEM
;
goto
out
;
}
nskb
=
skb_realloc_headroom
(
*
pskb
,
hh_len
);
if
(
!
nskb
)
return
-
1
;
if
((
*
pskb
)
->
sk
)
skb_set_owner_w
(
nskb
,
(
*
pskb
)
->
sk
);
kfree_skb
(
*
pskb
);
*
pskb
=
nskb
;
}
out:
if
(
dev_src
)
dev_put
(
dev_src
);
return
err
;
return
0
;
}
int
skb_ip_make_writable
(
struct
sk_buff
**
pskb
,
unsigned
int
writable_len
)
...
...
net/core/pktgen.c
View file @
42e8ae0c
...
...
@@ -47,6 +47,9 @@
* Also moved to /proc/net/pktgen/
* --ro
*
* Fix refcount off by one if first packet fails, potential null deref,
* memleak 030710- KJP
*
* See Documentation/networking/pktgen.txt for how to use this.
*/
...
...
@@ -85,9 +88,9 @@
#define cycles() ((u32)get_cycles())
#define VERSION "pktgen version 1.
2
"
#define VERSION "pktgen version 1.
3
"
static
char
version
[]
__initdata
=
"pktgen.c: v1.
2
: Packet Generator for packet performance testing.
\n
"
;
"pktgen.c: v1.
3
: Packet Generator for packet performance testing.
\n
"
;
/* Used to help with determining the pkts on receive */
...
...
@@ -611,12 +614,11 @@ static void inject(struct pktgen_info* info)
kfree_skb
(
skb
);
skb
=
fill_packet
(
odev
,
info
);
if
(
skb
==
NULL
)
{
break
;
goto
out_reldev
;
}
fp
++
;
fp_tmp
=
0
;
/* reset counter */
}
atomic_inc
(
&
skb
->
users
);
}
nr_frags
=
skb_shinfo
(
skb
)
->
nr_frags
;
...
...
@@ -624,7 +626,11 @@ static void inject(struct pktgen_info* info)
spin_lock_bh
(
&
odev
->
xmit_lock
);
if
(
!
netif_queue_stopped
(
odev
))
{
atomic_inc
(
&
skb
->
users
);
if
(
odev
->
hard_start_xmit
(
skb
,
odev
))
{
atomic_dec
(
&
skb
->
users
);
if
(
net_ratelimit
())
{
printk
(
KERN_INFO
"Hard xmit error
\n
"
);
}
...
...
@@ -729,15 +735,15 @@ static void inject(struct pktgen_info* info)
(
unsigned
long
long
)
info
->
errors
);
}
kfree_skb
(
skb
);
out_reldev:
if
(
odev
)
{
dev_put
(
odev
);
odev
=
NULL
;
}
/* TODO: Is this worth printing out (other than for debug?) */
printk
(
"fp = %llu
\n
"
,
(
unsigned
long
long
)
fp
);
return
;
}
...
...
@@ -953,7 +959,8 @@ static int proc_write(struct file *file, const char *user_buffer,
if
(
len
<
0
)
return
len
;
memset
(
name
,
0
,
sizeof
(
name
));
copy_from_user
(
name
,
&
user_buffer
[
i
],
len
);
if
(
copy_from_user
(
name
,
&
user_buffer
[
i
],
len
))
return
-
EFAULT
;
i
+=
len
;
max
=
count
-
i
;
...
...
@@ -1083,18 +1090,20 @@ static int proc_write(struct file *file, const char *user_buffer,
if
(
len
<
0
)
return
len
;
memset
(
info
->
outdev
,
0
,
sizeof
(
info
->
outdev
));
copy_from_user
(
info
->
outdev
,
&
user_buffer
[
i
],
len
);
if
(
copy_from_user
(
info
->
outdev
,
&
user_buffer
[
i
],
len
))
return
-
EFAULT
;
i
+=
len
;
sprintf
(
result
,
"OK: odev=%s"
,
info
->
outdev
);
return
count
;
}
if
(
!
strcmp
(
name
,
"flag"
))
{
char
f
[
32
];
memset
(
f
,
0
,
32
);
len
=
strn_len
(
&
user_buffer
[
i
],
sizeof
(
f
)
-
1
);
if
(
len
<
0
)
return
len
;
copy_from_user
(
f
,
&
user_buffer
[
i
],
len
);
memset
(
f
,
0
,
32
);
if
(
copy_from_user
(
f
,
&
user_buffer
[
i
],
len
))
return
-
EFAULT
;
i
+=
len
;
if
(
strcmp
(
f
,
"IPSRC_RND"
)
==
0
)
{
info
->
flags
|=
F_IPSRC_RND
;
...
...
@@ -1146,7 +1155,8 @@ static int proc_write(struct file *file, const char *user_buffer,
if
(
len
<
0
)
return
len
;
memset
(
info
->
dst_min
,
0
,
sizeof
(
info
->
dst_min
));
copy_from_user
(
info
->
dst_min
,
&
user_buffer
[
i
],
len
);
if
(
copy_from_user
(
info
->
dst_min
,
&
user_buffer
[
i
],
len
))
return
-
EFAULT
;
if
(
debug
)
printk
(
"pg: dst_min set to: %s
\n
"
,
info
->
dst_min
);
i
+=
len
;
...
...
@@ -1158,7 +1168,8 @@ static int proc_write(struct file *file, const char *user_buffer,
if
(
len
<
0
)
return
len
;
memset
(
info
->
dst_max
,
0
,
sizeof
(
info
->
dst_max
));
copy_from_user
(
info
->
dst_max
,
&
user_buffer
[
i
],
len
);
if
(
copy_from_user
(
info
->
dst_max
,
&
user_buffer
[
i
],
len
))
return
-
EFAULT
;
if
(
debug
)
printk
(
"pg: dst_max set to: %s
\n
"
,
info
->
dst_max
);
i
+=
len
;
...
...
@@ -1170,7 +1181,8 @@ static int proc_write(struct file *file, const char *user_buffer,
if
(
len
<
0
)
return
len
;
memset
(
info
->
src_min
,
0
,
sizeof
(
info
->
src_min
));
copy_from_user
(
info
->
src_min
,
&
user_buffer
[
i
],
len
);
if
(
copy_from_user
(
info
->
src_min
,
&
user_buffer
[
i
],
len
))
return
-
EFAULT
;
if
(
debug
)
printk
(
"pg: src_min set to: %s
\n
"
,
info
->
src_min
);
i
+=
len
;
...
...
@@ -1182,7 +1194,8 @@ static int proc_write(struct file *file, const char *user_buffer,
if
(
len
<
0
)
return
len
;
memset
(
info
->
src_max
,
0
,
sizeof
(
info
->
src_max
));
copy_from_user
(
info
->
src_max
,
&
user_buffer
[
i
],
len
);
if
(
copy_from_user
(
info
->
src_max
,
&
user_buffer
[
i
],
len
))
return
-
EFAULT
;
if
(
debug
)
printk
(
"pg: src_max set to: %s
\n
"
,
info
->
src_max
);
i
+=
len
;
...
...
@@ -1197,7 +1210,8 @@ static int proc_write(struct file *file, const char *user_buffer,
if
(
len
<
0
)
return
len
;
memset
(
valstr
,
0
,
sizeof
(
valstr
));
copy_from_user
(
valstr
,
&
user_buffer
[
i
],
len
);
if
(
copy_from_user
(
valstr
,
&
user_buffer
[
i
],
len
))
return
-
EFAULT
;
i
+=
len
;
for
(
*
m
=
0
;
*
v
&&
m
<
info
->
dst_mac
+
6
;
v
++
)
{
...
...
@@ -1229,7 +1243,8 @@ static int proc_write(struct file *file, const char *user_buffer,
if
(
len
<
0
)
return
len
;
memset
(
valstr
,
0
,
sizeof
(
valstr
));
copy_from_user
(
valstr
,
&
user_buffer
[
i
],
len
);
if
(
copy_from_user
(
valstr
,
&
user_buffer
[
i
],
len
))
return
-
EFAULT
;
i
+=
len
;
for
(
*
m
=
0
;
*
v
&&
m
<
info
->
src_mac
+
6
;
v
++
)
{
...
...
net/core/rtnetlink.c
View file @
42e8ae0c
...
...
@@ -191,9 +191,18 @@ static int rtnetlink_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
if
(
dev
->
master
)
RTA_PUT
(
skb
,
IFLA_MASTER
,
sizeof
(
int
),
&
dev
->
master
->
ifindex
);
if
(
dev
->
get_stats
)
{
struct
net_device_stats
*
stats
=
dev
->
get_stats
(
dev
);
if
(
stats
)
RTA_PUT
(
skb
,
IFLA_STATS
,
sizeof
(
*
stats
),
stats
);
unsigned
long
*
stats
=
(
unsigned
long
*
)
dev
->
get_stats
(
dev
);
if
(
stats
)
{
struct
rtattr
*
a
;
__u32
*
s
;
int
i
;
int
n
=
sizeof
(
struct
rtnl_link_stats
)
/
4
;
a
=
__RTA_PUT
(
skb
,
IFLA_STATS
,
n
*
4
);
s
=
RTA_DATA
(
a
);
for
(
i
=
0
;
i
<
n
;
i
++
)
s
[
i
]
=
stats
[
i
];
}
}
nlh
->
nlmsg_len
=
skb
->
tail
-
b
;
return
skb
->
len
;
...
...
net/core/sysctl_net_core.c
View file @
42e8ae0c
...
...
@@ -86,7 +86,7 @@ ctl_table core_table[] = {
{
.
ctl_name
=
NET_CORE_NO_CONG_THRESH
,
.
procname
=
"no_cong_thresh"
,
.
data
=
&
no_cong
,
.
data
=
&
no_cong
_thresh
,
.
maxlen
=
sizeof
(
int
),
.
mode
=
0644
,
.
proc_handler
=
&
proc_dointvec
...
...
net/decnet/af_decnet.c
View file @
42e8ae0c
...
...
@@ -2308,6 +2308,7 @@ static int dn_socket_seq_open(struct inode *inode, struct file *file)
}
static
struct
file_operations
dn_socket_seq_fops
=
{
.
owner
=
THIS_MODULE
,
.
open
=
dn_socket_seq_open
,
.
read
=
seq_read
,
.
llseek
=
seq_lseek
,
...
...
net/decnet/dn_dev.c
View file @
42e8ae0c
...
...
@@ -1443,6 +1443,7 @@ static int dn_dev_seq_open(struct inode *inode, struct file *file)
}
static
struct
file_operations
dn_dev_seq_fops
=
{
.
owner
=
THIS_MODULE
,
.
open
=
dn_dev_seq_open
,
.
read
=
seq_read
,
.
llseek
=
seq_lseek
,
...
...
net/decnet/dn_route.c
View file @
42e8ae0c
...
...
@@ -1766,6 +1766,7 @@ static int dn_rt_cache_seq_open(struct inode *inode, struct file *file)
}
static
struct
file_operations
dn_rt_cache_seq_fops
=
{
.
owner
=
THIS_MODULE
,
.
open
=
dn_rt_cache_seq_open
,
.
read
=
seq_read
,
.
llseek
=
seq_lseek
,
...
...
net/ipv4/ip_output.c
View file @
42e8ae0c
...
...
@@ -1313,7 +1313,7 @@ void __init ip_init(void)
ip_rt_init
();
inet_initpeers
();
#if
def CONFIG_IP_MULTICAST
#if
defined(CONFIG_IP_MULTICAST) && defined(CONFIG_PROC_FS)
igmp_mc_proc_init
();
#endif
}
net/ipv4/netfilter/ip_conntrack_core.c
View file @
42e8ae0c
...
...
@@ -251,7 +251,7 @@ static void unexpect_related(struct ip_conntrack_expect *expect)
}
/* delete all unconfirmed expectations for this conntrack */
static
void
remove_expectations
(
struct
ip_conntrack
*
ct
)
static
void
remove_expectations
(
struct
ip_conntrack
*
ct
,
int
drop_refcount
)
{
struct
list_head
*
exp_entry
,
*
next
;
struct
ip_conntrack_expect
*
exp
;
...
...
@@ -266,8 +266,11 @@ static void remove_expectations(struct ip_conntrack *ct)
* the un-established ones only */
if
(
exp
->
sibling
)
{
DEBUGP
(
"remove_expectations: skipping established %p of %p
\n
"
,
exp
->
sibling
,
ct
);
/* Indicate that this expectations parent is dead */
exp
->
expectant
=
NULL
;
if
(
drop_refcount
)
{
/* Indicate that this expectations parent is dead */
ip_conntrack_put
(
exp
->
expectant
);
exp
->
expectant
=
NULL
;
}
continue
;
}
...
...
@@ -292,7 +295,7 @@ clean_from_lists(struct ip_conntrack *ct)
&
ct
->
tuplehash
[
IP_CT_DIR_REPLY
]);
/* Destroy all un-established, pending expectations */
remove_expectations
(
ct
);
remove_expectations
(
ct
,
1
);
}
static
void
...
...
@@ -1117,7 +1120,7 @@ static inline int unhelp(struct ip_conntrack_tuple_hash *i,
{
if
(
i
->
ctrack
->
helper
==
me
)
{
/* Get rid of any expected. */
remove_expectations
(
i
->
ctrack
);
remove_expectations
(
i
->
ctrack
,
0
);
/* And *then* set helper to NULL */
i
->
ctrack
->
helper
=
NULL
;
}
...
...
net/ipv4/netfilter/ip_conntrack_irc.c
View file @
42e8ae0c
...
...
@@ -54,7 +54,7 @@ MODULE_PARM_DESC(dcc_timeout, "timeout on for unestablished DCC channels");
#endif
static
char
*
dccprotos
[]
=
{
"SEND "
,
"CHAT "
,
"MOVE "
,
"TSEND "
,
"SCHAT "
};
#define M
AXMATCHLEN 6
#define M
INMATCHLEN 5
DECLARE_LOCK
(
ip_irc_lock
);
struct
module
*
ip_conntrack_irc
=
THIS_MODULE
;
...
...
@@ -87,9 +87,11 @@ int parse_dcc(char *data, char *data_end, u_int32_t * ip, u_int16_t * port,
*
ip
=
simple_strtoul
(
data
,
&
data
,
10
);
/* skip blanks between ip and port */
while
(
*
data
==
' '
)
while
(
*
data
==
' '
)
{
if
(
data
>=
data_end
)
return
-
1
;
data
++
;
}
*
port
=
simple_strtoul
(
data
,
&
data
,
10
);
*
ad_end_p
=
data
;
...
...
@@ -139,13 +141,17 @@ static int help(struct sk_buff *skb,
data
=
irc_buffer
;
data_limit
=
irc_buffer
+
skb
->
len
-
dataoff
;
while
(
data
<
(
data_limit
-
(
22
+
MAXMATCHLEN
)))
{
/* strlen("\1DCC SENT t AAAAAAAA P\1\n")=24
* 5+MINMATCHLEN+strlen("t AAAAAAAA P\1\n")=14 */
while
(
data
<
(
data_limit
-
(
19
+
MINMATCHLEN
)))
{
if
(
memcmp
(
data
,
"
\1
DCC "
,
5
))
{
data
++
;
continue
;
}
data
+=
5
;
/* we have at least (19+MINMATCHLEN)-5 bytes valid data left */
DEBUGP
(
"DCC found in master %u.%u.%u.%u:%u %u.%u.%u.%u:%u...
\n
"
,
NIPQUAD
(
iph
->
saddr
),
ntohs
(
tcph
.
source
),
...
...
@@ -159,6 +165,9 @@ static int help(struct sk_buff *skb,
DEBUGP
(
"DCC %s detected
\n
"
,
dccprotos
[
i
]);
data
+=
strlen
(
dccprotos
[
i
]);
/* we have at least
* (19+MINMATCHLEN)-5-dccprotos[i].matchlen bytes valid
* data left (== 14/13 bytes) */
if
(
parse_dcc
((
char
*
)
data
,
data_limit
,
&
dcc_ip
,
&
dcc_port
,
&
addr_beg_p
,
&
addr_end_p
))
{
/* unable to parse */
...
...
net/ipv4/netfilter/ipt_MIRROR.c
View file @
42e8ae0c
...
...
@@ -9,6 +9,12 @@
Changes:
25 Aug 2001 Harald Welte <laforge@gnumonks.org>
- decrement and check TTL if not called from FORWARD hook
18 Jul 2003 Harald Welte <laforge@netfilter.org>
- merge Patrick McHardy's mirror fixes from 2.4.22 to
2.6.0-test1
19 Jul 2003 Harald Welte <laforge@netfilter.org>
- merge Patrick McHardy's rp_filter fixes from 2.4.22 to
2.6.0-test1
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
...
...
@@ -32,7 +38,6 @@
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netdevice.h>
#include <linux/route.h>
struct
in_device
;
#include <net/route.h>
#if 0
...
...
@@ -41,46 +46,58 @@ struct in_device;
#define DEBUGP(format, args...)
#endif
static
in
t
route_mirror
(
struct
sk_buff
*
skb
)
static
in
line
struct
rtable
*
route_mirror
(
struct
sk_buff
*
skb
,
int
local
)
{
struct
iphdr
*
iph
=
skb
->
nh
.
iph
;
struct
flowi
fl
=
{
.
nl_u
=
{
.
ip4_u
=
{
.
daddr
=
iph
->
saddr
,
.
saddr
=
iph
->
daddr
,
.
tos
=
RT_TOS
(
iph
->
tos
)
|
RTO_CONN
}
}
};
struct
dst_entry
*
odst
;
struct
flowi
fl
=
{};
struct
rtable
*
rt
;
/* Backwards */
if
(
ip_route_output_key
(
&
rt
,
&
fl
))
{
return
0
;
if
(
local
)
{
fl
.
nl_u
.
ip4_u
.
daddr
=
iph
->
saddr
;
fl
.
nl_u
.
ip4_u
.
saddr
=
iph
->
daddr
;
fl
.
nl_u
.
ip4_u
.
tos
=
RT_TOS
(
iph
->
tos
);
if
(
ip_route_output_key
(
&
rt
,
&
fl
)
!=
0
)
return
NULL
;
}
else
{
/* non-local src, find valid iif to satisfy
* rp-filter when calling ip_route_input(). */
fl
.
nl_u
.
ip4_u
.
daddr
=
iph
->
daddr
;
if
(
ip_route_output_key
(
&
rt
,
&
fl
)
!=
0
)
return
NULL
;
odst
=
skb
->
dst
;
if
(
ip_route_input
(
skb
,
iph
->
saddr
,
iph
->
daddr
,
RT_TOS
(
iph
->
tos
),
rt
->
u
.
dst
.
dev
)
!=
0
)
{
dst_release
(
&
rt
->
u
.
dst
);
return
NULL
;
}
dst_release
(
&
rt
->
u
.
dst
);
rt
=
(
struct
rtable
*
)
skb
->
dst
;
skb
->
dst
=
odst
;
}
/* check if the interface we are leaving by is the same as the
one we arrived on */
if
(
skb
->
dev
==
rt
->
u
.
dst
.
dev
)
{
/* Drop old route. */
dst_release
(
skb
->
dst
);
skb
->
dst
=
&
rt
->
u
.
dst
;
return
1
;
if
(
rt
->
u
.
dst
.
error
)
{
dst_release
(
&
rt
->
u
.
dst
);
rt
=
NULL
;
}
return
0
;
return
rt
;
}
static
in
t
ip_rewrite
(
struct
sk_buff
**
p
skb
)
static
in
line
void
ip_rewrite
(
struct
sk_buff
*
skb
)
{
u32
odaddr
,
osaddr
;
if
(
!
skb_ip_make_writable
(
pskb
,
sizeof
(
struct
iphdr
)))
return
0
;
odaddr
=
skb
->
nh
.
iph
->
saddr
;
osaddr
=
skb
->
nh
.
iph
->
daddr
;
odaddr
=
(
*
pskb
)
->
nh
.
iph
->
saddr
;
osaddr
=
(
*
pskb
)
->
nh
.
iph
->
daddr
;
(
*
pskb
)
->
nfcache
|=
NFC_ALTERED
;
skb
->
nfcache
|=
NFC_ALTERED
;
/* Rewrite IP header */
(
*
pskb
)
->
nh
.
iph
->
daddr
=
odaddr
;
(
*
pskb
)
->
nh
.
iph
->
saddr
=
osaddr
;
return
1
;
skb
->
nh
.
iph
->
daddr
=
odaddr
;
skb
->
nh
.
iph
->
saddr
=
osaddr
;
}
/* Stolen from ip_finish_output2 */
...
...
@@ -113,31 +130,51 @@ static unsigned int ipt_mirror_target(struct sk_buff **pskb,
const
void
*
targinfo
,
void
*
userinfo
)
{
if
(((
*
pskb
)
->
dst
!=
NULL
)
&&
route_mirror
(
*
pskb
))
{
if
(
!
ip_rewrite
(
pskb
))
return
NF_DROP
;
struct
rtable
*
rt
;
struct
sk_buff
*
nskb
;
unsigned
int
hh_len
;
/* If we are not at FORWARD hook (INPUT/PREROUTING),
* the TTL isn't decreased by the IP stack */
if
(
hooknum
!=
NF_IP_FORWARD
)
{
if
((
*
pskb
)
->
nh
.
iph
->
ttl
<=
1
)
{
/* this will traverse normal stack, and
* thus call conntrack on the icmp packet */
icmp_send
(
*
pskb
,
ICMP_TIME_EXCEEDED
,
ICMP_EXC_TTL
,
0
);
return
NF_DROP
;
}
/* Made writable by ip_rewrite */
ip_decrease_ttl
((
*
pskb
)
->
nh
.
iph
);
/* Make skb writable */
if
(
!
skb_ip_make_writable
(
pskb
,
sizeof
(
struct
iphdr
)))
return
0
;
/* If we are not at FORWARD hook (INPUT/PREROUTING),
* the TTL isn't decreased by the IP stack */
if
(
hooknum
!=
NF_IP_FORWARD
)
{
if
((
*
pskb
)
->
nh
.
iph
->
ttl
<=
1
)
{
/* this will traverse normal stack, and
* thus call conntrack on the icmp packet */
icmp_send
(
*
pskb
,
ICMP_TIME_EXCEEDED
,
ICMP_EXC_TTL
,
0
);
return
NF_DROP
;
}
ip_decrease_ttl
((
*
pskb
)
->
nh
.
iph
);
}
/* Don't let conntrack code see this packet:
it will think we are starting a new
connection! --RR */
ip_direct_send
(
*
pskb
);
if
((
rt
=
route_mirror
(
*
pskb
,
hooknum
==
NF_IP_LOCAL_IN
))
==
NULL
)
return
NF_DROP
;
return
NF_STOLEN
;
hh_len
=
(
rt
->
u
.
dst
.
dev
->
hard_header_len
+
15
)
&
~
15
;
/* Copy skb (even if skb is about to be dropped, we can't just
* clone it because there may be other things, such as tcpdump,
* interested in it). We also need to expand headroom in case
* hh_len of incoming interface < hh_len of outgoing interface */
nskb
=
skb_copy_expand
(
*
pskb
,
hh_len
,
skb_tailroom
(
*
pskb
),
GFP_ATOMIC
);
if
(
nskb
==
NULL
)
{
dst_release
(
&
rt
->
u
.
dst
);
return
NF_DROP
;
}
dst_release
(
nskb
->
dst
);
nskb
->
dst
=
&
rt
->
u
.
dst
;
ip_rewrite
(
nskb
);
/* Don't let conntrack code see this packet:
* it will think we are starting a new
* connection! --RR */
ip_direct_send
(
nskb
);
return
NF_DROP
;
}
...
...
net/ipv4/netfilter/ipt_REJECT.c
View file @
42e8ae0c
/*
* This is a module which is used for rejecting packets.
* Added support for customized reject packets (Jozsef Kadlecsik).
* Added support for ICMP type-3-code-13 (Maciej Soltysiak). [RFC 1812]
*/
#include <linux/config.h>
#include <linux/module.h>
...
...
@@ -35,134 +36,180 @@ static void connection_attach(struct sk_buff *new_skb, struct nf_ct_info *nfct)
}
}
static
inline
struct
rtable
*
route_reverse
(
struct
sk_buff
*
skb
,
int
local
)
{
struct
iphdr
*
iph
=
skb
->
nh
.
iph
;
struct
dst_entry
*
odst
;
struct
flowi
fl
=
{};
struct
rtable
*
rt
;
if
(
local
)
{
fl
.
nl_u
.
ip4_u
.
daddr
=
iph
->
saddr
;
fl
.
nl_u
.
ip4_u
.
saddr
=
iph
->
daddr
;
fl
.
nl_u
.
ip4_u
.
tos
=
RT_TOS
(
iph
->
tos
);
if
(
ip_route_output_key
(
&
rt
,
&
fl
)
!=
0
)
return
NULL
;
}
else
{
/* non-local src, find valid iif to satisfy
* rp-filter when calling ip_route_input. */
fl
.
nl_u
.
ip4_u
.
daddr
=
iph
->
daddr
;
if
(
ip_route_output_key
(
&
rt
,
&
fl
)
!=
0
)
return
NULL
;
odst
=
skb
->
dst
;
if
(
ip_route_input
(
skb
,
iph
->
saddr
,
iph
->
daddr
,
RT_TOS
(
iph
->
tos
),
rt
->
u
.
dst
.
dev
)
!=
0
)
{
dst_release
(
&
rt
->
u
.
dst
);
return
NULL
;
}
dst_release
(
&
rt
->
u
.
dst
);
rt
=
(
struct
rtable
*
)
skb
->
dst
;
skb
->
dst
=
odst
;
}
if
(
rt
->
u
.
dst
.
error
)
{
dst_release
(
&
rt
->
u
.
dst
);
rt
=
NULL
;
}
return
rt
;
}
/* Send RST reply */
static
unsigned
int
send_reset
(
struct
sk_buff
**
p
skb
,
int
local
)
static
void
send_reset
(
struct
sk_buff
*
old
skb
,
int
local
)
{
struct
tcphdr
tcph
;
struct
sk_buff
*
nskb
;
struct
tcphdr
*
otcph
,
*
tcph
;
struct
rtable
*
rt
;
unsigned
int
otcplen
;
u_int16_t
tmp_port
;
u_int32_t
tmp_addr
;
int
needs_ack
,
hh_len
,
datalen
;
struct
nf_ct_info
*
oldnfct
;
int
needs_ack
;
int
hh_len
;
/* No RSTs for fragments. */
if
((
*
pskb
)
->
nh
.
iph
->
frag_off
&
htons
(
IP_OFFSET
))
return
NF_DROP
;
/* IP header checks: fragment, too short. */
if
(
oldskb
->
nh
.
iph
->
frag_off
&
htons
(
IP_OFFSET
)
||
oldskb
->
len
<
(
oldskb
->
nh
.
iph
->
ihl
<<
2
)
+
sizeof
(
struct
tcphdr
))
return
;
if
(
skb_copy_bits
(
*
pskb
,
(
*
pskb
)
->
nh
.
iph
->
ihl
*
4
,
&
tcph
,
sizeof
(
tcph
))
<
0
)
return
NF_DROP
;
otcph
=
(
struct
tcphdr
*
)((
u_int32_t
*
)
oldskb
->
nh
.
iph
+
oldskb
->
nh
.
iph
->
ihl
);
otcplen
=
oldskb
->
len
-
oldskb
->
nh
.
iph
->
ihl
*
4
;
if
(
skb_copy_bits
(
oldskb
,
oldskb
->
nh
.
iph
->
ihl
*
4
,
otcph
,
sizeof
(
*
otcph
))
<
0
)
return
;
/* No RST for RST. */
if
(
tcph
.
rst
)
return
NF_DROP
;
if
(
otcph
->
rst
)
return
;
/* FIXME: Check checksum. */
{
struct
flowi
fl
=
{
.
nl_u
=
{
.
ip4_u
=
{
.
daddr
=
(
*
pskb
)
->
nh
.
iph
->
saddr
,
.
saddr
=
(
local
?
(
*
pskb
)
->
nh
.
iph
->
daddr
:
0
),
.
tos
=
RT_TOS
((
*
pskb
)
->
nh
.
iph
->
tos
)
}
}
};
/* Check checksum. */
if
(
tcp_v4_check
(
otcph
,
otcplen
,
oldskb
->
nh
.
iph
->
saddr
,
oldskb
->
nh
.
iph
->
daddr
,
csum_partial
((
char
*
)
otcph
,
otcplen
,
0
))
!=
0
)
return
;
/* Routing: if not headed for us, route won't like source */
if
(
ip_route_output_key
(
&
rt
,
&
fl
))
return
NF_DROP
;
if
((
rt
=
route_reverse
(
oldskb
,
local
))
==
NULL
)
return
;
hh_len
=
(
rt
->
u
.
dst
.
dev
->
hard_header_len
+
15
)
&~
15
;
}
hh_len
=
(
rt
->
u
.
dst
.
dev
->
hard_header_len
+
15
)
&~
15
;
/* We're going to flip the header around, drop options and data. */
if
(
!
skb_ip_make_writable
(
pskb
,
(
*
pskb
)
->
nh
.
iph
->
ihl
*
4
+
sizeof
(
tcph
)))
{
ip_rt_put
(
rt
);
return
NF_DROP
;
/* Copy skb (even if skb is about to be dropped, we can't just
clone it because there may be other things, such as tcpdump,
interested in it). We also need to expand headroom in case
hh_len of incoming interface < hh_len of outgoing interface */
nskb
=
skb_copy_expand
(
oldskb
,
hh_len
,
skb_tailroom
(
oldskb
),
GFP_ATOMIC
);
if
(
!
nskb
)
{
dst_release
(
&
rt
->
u
.
dst
);
return
;
}
(
*
pskb
)
->
h
.
th
=
(
void
*
)(
*
pskb
)
->
nh
.
iph
+
sizeof
(
tcph
);
datalen
=
(
*
pskb
)
->
len
-
(
*
pskb
)
->
nh
.
iph
->
ihl
*
4
-
tcph
.
doff
*
4
;
/* Change over route. */
dst_release
((
*
pskb
)
->
dst
);
(
*
pskb
)
->
dst
=
&
rt
->
u
.
dst
;
dst_release
(
nskb
->
dst
);
nskb
->
dst
=
&
rt
->
u
.
dst
;
/* This packet will not be the same as the other: clear nf fields */
(
*
pskb
)
->
nfcache
=
0
;
nf_conntrack_put
(
nskb
->
nfct
);
nskb
->
nfct
=
NULL
;
nskb
->
nfcache
=
0
;
#ifdef CONFIG_NETFILTER_DEBUG
(
*
pskb
)
->
nf_debug
=
0
;
nskb
->
nf_debug
=
0
;
#endif
(
*
pskb
)
->
nfmark
=
0
;
nskb
->
nfmark
=
0
;
tcph
=
(
struct
tcphdr
*
)((
u_int32_t
*
)
nskb
->
nh
.
iph
+
nskb
->
nh
.
iph
->
ihl
);
/* Swap source and dest */
tmp_addr
=
(
*
pskb
)
->
nh
.
iph
->
saddr
;
(
*
pskb
)
->
nh
.
iph
->
saddr
=
(
*
pskb
)
->
nh
.
iph
->
daddr
;
(
*
pskb
)
->
nh
.
iph
->
daddr
=
tmp_addr
;
tmp_port
=
(
*
pskb
)
->
h
.
t
h
->
source
;
(
*
pskb
)
->
h
.
th
->
source
=
(
*
pskb
)
->
h
.
t
h
->
dest
;
(
*
pskb
)
->
h
.
t
h
->
dest
=
tmp_port
;
tmp_addr
=
nskb
->
nh
.
iph
->
saddr
;
nskb
->
nh
.
iph
->
saddr
=
nskb
->
nh
.
iph
->
daddr
;
nskb
->
nh
.
iph
->
daddr
=
tmp_addr
;
tmp_port
=
tcp
h
->
source
;
tcph
->
source
=
tcp
h
->
dest
;
tcp
h
->
dest
=
tmp_port
;
/* Truncate to length (no data) */
(
*
pskb
)
->
h
.
t
h
->
doff
=
sizeof
(
struct
tcphdr
)
/
4
;
skb_trim
(
*
pskb
,
(
*
pskb
)
->
nh
.
iph
->
ihl
*
4
+
sizeof
(
struct
tcphdr
));
(
*
pskb
)
->
nh
.
iph
->
tot_len
=
htons
((
*
pskb
)
->
len
);
tcp
h
->
doff
=
sizeof
(
struct
tcphdr
)
/
4
;
skb_trim
(
nskb
,
nskb
->
nh
.
iph
->
ihl
*
4
+
sizeof
(
struct
tcphdr
));
nskb
->
nh
.
iph
->
tot_len
=
htons
(
nskb
->
len
);
if
(
(
*
pskb
)
->
h
.
t
h
->
ack
)
{
if
(
tcp
h
->
ack
)
{
needs_ack
=
0
;
(
*
pskb
)
->
h
.
th
->
seq
=
tcph
.
ack_seq
;
(
*
pskb
)
->
h
.
t
h
->
ack_seq
=
0
;
tcph
->
seq
=
otcph
->
ack_seq
;
tcp
h
->
ack_seq
=
0
;
}
else
{
needs_ack
=
1
;
(
*
pskb
)
->
h
.
th
->
ack_seq
=
htonl
(
ntohl
(
tcph
.
seq
)
+
tcph
.
syn
+
tcph
.
fin
+
datalen
);
(
*
pskb
)
->
h
.
th
->
seq
=
0
;
tcph
->
ack_seq
=
htonl
(
ntohl
(
otcph
->
seq
)
+
otcph
->
syn
+
otcph
->
fin
+
otcplen
-
(
otcph
->
doff
<<
2
));
tcph
->
seq
=
0
;
}
/* Reset flags */
memset
((
*
pskb
)
->
h
.
raw
+
13
,
0
,
1
)
;
(
*
pskb
)
->
h
.
t
h
->
rst
=
1
;
(
*
pskb
)
->
h
.
t
h
->
ack
=
needs_ack
;
((
u_int8_t
*
)
tcph
)[
13
]
=
0
;
tcp
h
->
rst
=
1
;
tcp
h
->
ack
=
needs_ack
;
(
*
pskb
)
->
h
.
t
h
->
window
=
0
;
(
*
pskb
)
->
h
.
t
h
->
urg_ptr
=
0
;
tcp
h
->
window
=
0
;
tcp
h
->
urg_ptr
=
0
;
/* Adjust TCP checksum */
(
*
pskb
)
->
h
.
th
->
check
=
0
;
(
*
pskb
)
->
h
.
th
->
check
=
tcp_v4_check
((
*
pskb
)
->
h
.
th
,
sizeof
(
struct
tcphdr
),
(
*
pskb
)
->
nh
.
iph
->
saddr
,
(
*
pskb
)
->
nh
.
iph
->
daddr
,
csum_partial
((
*
pskb
)
->
h
.
raw
,
sizeof
(
struct
tcphdr
),
0
));
tcph
->
check
=
0
;
tcph
->
check
=
tcp_v4_check
(
tcph
,
sizeof
(
struct
tcphdr
),
nskb
->
nh
.
iph
->
saddr
,
nskb
->
nh
.
iph
->
daddr
,
csum_partial
((
char
*
)
tcph
,
sizeof
(
struct
tcphdr
),
0
));
/* Adjust IP TTL, DF */
(
*
pskb
)
->
nh
.
iph
->
ttl
=
MAXTTL
;
nskb
->
nh
.
iph
->
ttl
=
MAXTTL
;
/* Set DF, id = 0 */
(
*
pskb
)
->
nh
.
iph
->
frag_off
=
htons
(
IP_DF
);
(
*
pskb
)
->
nh
.
iph
->
id
=
0
;
nskb
->
nh
.
iph
->
frag_off
=
htons
(
IP_DF
);
nskb
->
nh
.
iph
->
id
=
0
;
/* Adjust IP checksum */
(
*
pskb
)
->
nh
.
iph
->
check
=
0
;
(
*
pskb
)
->
nh
.
iph
->
check
=
ip_fast_csum
((
*
pskb
)
->
nh
.
raw
,
(
*
pskb
)
->
nh
.
iph
->
ihl
);
nskb
->
nh
.
iph
->
check
=
0
;
nskb
->
nh
.
iph
->
check
=
ip_fast_csum
((
unsigned
char
*
)
nskb
->
nh
.
iph
,
nskb
->
nh
.
iph
->
ihl
);
/* "Never happens" */
if
(
(
*
pskb
)
->
len
>
dst_pmtu
((
*
pskb
)
->
dst
))
return
NF_DROP
;
if
(
nskb
->
len
>
dst_pmtu
(
nskb
->
dst
))
goto
free_nskb
;
/* Related to old connection. */
oldnfct
=
(
*
pskb
)
->
nfct
;
connection_attach
(
*
pskb
,
oldnfct
);
nf_conntrack_put
(
oldnfct
);
connection_attach
(
nskb
,
oldskb
->
nfct
);
NF_HOOK
(
PF_INET
,
NF_IP_LOCAL_OUT
,
*
pskb
,
NULL
,
(
*
pskb
)
->
dst
->
dev
,
NF_HOOK
(
PF_INET
,
NF_IP_LOCAL_OUT
,
nskb
,
NULL
,
nskb
->
dst
->
dev
,
ip_finish_output
);
return
NF_STOLEN
;
return
;
free_nskb:
kfree_skb
(
nskb
);
}
static
void
send_unreach
(
const
struct
sk_buff
*
skb_in
,
int
code
)
static
void
send_unreach
(
struct
sk_buff
*
skb_in
,
int
code
)
{
struct
iphdr
*
iph
;
struct
udphdr
*
udph
;
struct
icmphdr
*
icmph
;
struct
sk_buff
*
nskb
;
u32
saddr
;
u8
tos
;
...
...
@@ -177,6 +224,8 @@ static void send_unreach(const struct sk_buff *skb_in, int code)
if
(
!
xrlim_allow
(
&
rt
->
u
.
dst
,
1
*
HZ
))
return
;
iph
=
skb_in
->
nh
.
iph
;
/* No replies to physical multicast/broadcast */
if
(
skb_in
->
pkt_type
!=
PACKET_HOST
)
return
;
...
...
@@ -186,38 +235,52 @@ static void send_unreach(const struct sk_buff *skb_in, int code)
return
;
/* Only reply to fragment 0. */
if
(
skb_in
->
nh
.
iph
->
frag_off
&
htons
(
IP_OFFSET
))
if
(
iph
->
frag_off
&
htons
(
IP_OFFSET
))
return
;
/* Ensure we have at least 8 bytes of proto header. */
if
(
skb_in
->
len
<
skb_in
->
nh
.
iph
->
ihl
*
4
+
8
)
return
;
/* if UDP checksum is set, verify it's correct */
if
(
iph
->
protocol
==
IPPROTO_UDP
&&
skb_in
->
tail
-
(
u8
*
)
iph
>=
sizeof
(
struct
udphdr
))
{
int
datalen
=
skb_in
->
len
-
(
iph
->
ihl
<<
2
);
udph
=
(
struct
udphdr
*
)((
char
*
)
iph
+
(
iph
->
ihl
<<
2
));
if
(
udph
->
check
&&
csum_tcpudp_magic
(
iph
->
saddr
,
iph
->
daddr
,
datalen
,
IPPROTO_UDP
,
csum_partial
((
char
*
)
udph
,
datalen
,
0
))
!=
0
)
return
;
}
/* If we send an ICMP error to an ICMP error a mess would result.. */
if
(
skb_in
->
nh
.
iph
->
protocol
==
IPPROTO_ICMP
)
{
struct
icmphdr
icmph
;
if
(
iph
->
protocol
==
IPPROTO_ICMP
&&
skb_in
->
tail
-
(
u8
*
)
iph
>=
sizeof
(
struct
icmphdr
))
{
icmph
=
(
struct
icmphdr
*
)((
char
*
)
iph
+
(
iph
->
ihl
<<
2
));
if
(
skb_copy_bits
(
skb_in
,
skb_in
->
nh
.
iph
->
ihl
*
4
,
&
icmph
,
sizeof
(
icmph
))
<
0
)
icmph
,
sizeof
(
*
icmph
))
<
0
)
return
;
/* Between echo-reply (0) and timestamp (13),
everything except echo-request (8) is an error.
Also, anything greater than NR_ICMP_TYPES is
unknown, and hence should be treated as an error... */
if
((
icmph
.
type
<
ICMP_TIMESTAMP
&&
icmph
.
type
!=
ICMP_ECHOREPLY
&&
icmph
.
type
!=
ICMP_ECHO
)
||
icmph
.
type
>
NR_ICMP_TYPES
)
if
((
icmph
->
type
<
ICMP_TIMESTAMP
&&
icmph
->
type
!=
ICMP_ECHOREPLY
&&
icmph
->
type
!=
ICMP_ECHO
)
||
icmph
->
type
>
NR_ICMP_TYPES
)
return
;
}
saddr
=
skb_in
->
nh
.
iph
->
daddr
;
saddr
=
iph
->
daddr
;
if
(
!
(
rt
->
rt_flags
&
RTCF_LOCAL
))
saddr
=
0
;
tos
=
(
skb_in
->
nh
.
iph
->
tos
&
IPTOS_TOS_MASK
)
|
IPTOS_PREC_INTERNETCONTROL
;
tos
=
(
iph
->
tos
&
IPTOS_TOS_MASK
)
|
IPTOS_PREC_INTERNETCONTROL
;
{
struct
flowi
fl
=
{
.
nl_u
=
{
.
ip4_u
=
{
.
daddr
=
skb_in
->
nh
.
iph
->
saddr
,
...
...
@@ -247,38 +310,41 @@ static void send_unreach(const struct sk_buff *skb_in, int code)
skb_reserve
(
nskb
,
hh_len
);
/* Set up IP header */
nskb
->
nh
.
iph
=
(
struct
iphdr
*
)
skb_put
(
nskb
,
sizeof
(
struct
iphdr
));
nskb
->
nh
.
iph
->
version
=
4
;
nskb
->
nh
.
iph
->
ihl
=
5
;
nskb
->
nh
.
iph
->
tos
=
tos
;
nskb
->
nh
.
iph
->
tot_len
=
htons
(
length
);
iph
=
nskb
->
nh
.
iph
=
(
struct
iphdr
*
)
skb_put
(
nskb
,
sizeof
(
struct
iphdr
));
iph
->
version
=
4
;
iph
->
ihl
=
5
;
iph
->
tos
=
tos
;
iph
->
tot_len
=
htons
(
length
);
/* PMTU discovery never applies to ICMP packets. */
nskb
->
nh
.
iph
->
frag_off
=
0
;
iph
->
frag_off
=
0
;
nskb
->
nh
.
iph
->
ttl
=
MAXTTL
;
ip_select_ident
(
nskb
->
nh
.
iph
,
&
rt
->
u
.
dst
,
NULL
);
nskb
->
nh
.
iph
->
protocol
=
IPPROTO_ICMP
;
nskb
->
nh
.
iph
->
saddr
=
rt
->
rt_src
;
nskb
->
nh
.
iph
->
daddr
=
rt
->
rt_dst
;
nskb
->
nh
.
iph
->
check
=
0
;
nskb
->
nh
.
iph
->
check
=
ip_fast_csum
(
nskb
->
nh
.
raw
,
nskb
->
nh
.
iph
->
ihl
);
iph
->
ttl
=
MAXTTL
;
ip_select_ident
(
iph
,
&
rt
->
u
.
dst
,
NULL
);
iph
->
protocol
=
IPPROTO_ICMP
;
iph
->
saddr
=
rt
->
rt_src
;
iph
->
daddr
=
rt
->
rt_dst
;
iph
->
check
=
0
;
iph
->
check
=
ip_fast_csum
((
unsigned
char
*
)
iph
,
iph
->
ihl
);
/* Set up ICMP header. */
nskb
->
h
.
icmph
=
(
struct
icmphdr
*
)
skb_put
(
nskb
,
sizeof
(
struct
icmphdr
));
nskb
->
h
.
icmph
->
type
=
ICMP_DEST_UNREACH
;
nskb
->
h
.
icmph
->
code
=
code
;
nskb
->
h
.
icmph
->
un
.
gateway
=
0
;
nskb
->
h
.
icmph
->
checksum
=
0
;
icmph
=
nskb
->
h
.
icmph
=
(
struct
icmphdr
*
)
skb_put
(
nskb
,
sizeof
(
struct
icmphdr
));
icmph
->
type
=
ICMP_DEST_UNREACH
;
icmph
->
code
=
code
;
icmph
->
un
.
gateway
=
0
;
icmph
->
checksum
=
0
;
/* Copy as much of original packet as will fit */
data
=
skb_put
(
nskb
,
length
-
sizeof
(
struct
iphdr
)
-
sizeof
(
struct
icmphdr
));
skb_copy_bits
(
skb_in
,
0
,
data
,
length
-
sizeof
(
struct
iphdr
)
-
sizeof
(
struct
icmphdr
));
nskb
->
h
.
icmph
->
checksum
=
ip_compute_csum
(
nskb
->
h
.
raw
,
length
-
sizeof
(
struct
iphdr
));
icmph
->
checksum
=
ip_compute_csum
((
unsigned
char
*
)
icmph
,
length
-
sizeof
(
struct
iphdr
));
connection_attach
(
nskb
,
skb_in
->
nfct
);
...
...
@@ -322,8 +388,11 @@ static unsigned int reject(struct sk_buff **pskb,
case
IPT_ICMP_HOST_PROHIBITED
:
send_unreach
(
*
pskb
,
ICMP_HOST_ANO
);
break
;
case
IPT_ICMP_ADMIN_PROHIBITED
:
send_unreach
(
*
pskb
,
ICMP_PKT_FILTERED
);
break
;
case
IPT_TCP_RESET
:
return
send_reset
(
pskb
,
hooknum
==
NF_IP_LOCAL_IN
);
send_reset
(
*
pskb
,
hooknum
==
NF_IP_LOCAL_IN
);
case
IPT_ICMP_ECHOREPLY
:
/* Doesn't happen. */
break
;
...
...
net/ipv4/netfilter/ipt_helper.c
View file @
42e8ae0c
...
...
@@ -10,6 +10,7 @@
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/netfilter_ipv4/ip_conntrack.h>
#include <linux/netfilter_ipv4/ip_conntrack_core.h>
#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv4/ipt_helper.h>
...
...
@@ -34,6 +35,7 @@ match(const struct sk_buff *skb,
struct
ip_conntrack_expect
*
exp
;
struct
ip_conntrack
*
ct
;
enum
ip_conntrack_info
ctinfo
;
int
ret
=
0
;
ct
=
ip_conntrack_get
((
struct
sk_buff
*
)
skb
,
&
ctinfo
);
if
(
!
ct
)
{
...
...
@@ -47,23 +49,27 @@ match(const struct sk_buff *skb,
}
exp
=
ct
->
master
;
READ_LOCK
(
&
ip_conntrack_lock
);
if
(
!
exp
->
expectant
)
{
DEBUGP
(
"ipt_helper: expectation %p without expectant !?!
\n
"
,
exp
);
return
0
;
goto
out_unlock
;
}
if
(
!
exp
->
expectant
->
helper
)
{
DEBUGP
(
"ipt_helper: master ct %p has no helper
\n
"
,
exp
->
expectant
);
return
0
;
goto
out_unlock
;
}
DEBUGP
(
"master's name = %s , info->name = %s
\n
"
,
exp
->
expectant
->
helper
->
name
,
info
->
name
);
return
!
strncmp
(
exp
->
expectant
->
helper
->
name
,
info
->
name
,
strlen
(
exp
->
expectant
->
helper
->
name
))
^
info
->
invert
;
ret
=
!
strncmp
(
exp
->
expectant
->
helper
->
name
,
info
->
name
,
strlen
(
exp
->
expectant
->
helper
->
name
))
^
info
->
invert
;
out_unlock:
READ_UNLOCK
(
&
ip_conntrack_lock
);
return
ret
;
}
static
int
check
(
const
char
*
tablename
,
...
...
net/ipv6/addrconf.c
View file @
42e8ae0c
...
...
@@ -130,7 +130,7 @@ static spinlock_t addrconf_verify_lock = SPIN_LOCK_UNLOCKED;
static
int
addrconf_ifdown
(
struct
net_device
*
dev
,
int
how
);
static
void
addrconf_dad_start
(
struct
inet6_ifaddr
*
ifp
);
static
void
addrconf_dad_start
(
struct
inet6_ifaddr
*
ifp
,
int
flags
);
static
void
addrconf_dad_timer
(
unsigned
long
data
);
static
void
addrconf_dad_completed
(
struct
inet6_ifaddr
*
ifp
);
static
void
addrconf_rs_timer
(
unsigned
long
data
);
...
...
@@ -710,7 +710,7 @@ static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, struct inet6_ifaddr *i
ift
->
prefered_lft
=
tmp_prefered_lft
;
ift
->
tstamp
=
ifp
->
tstamp
;
spin_unlock_bh
(
&
ift
->
lock
);
addrconf_dad_start
(
ift
);
addrconf_dad_start
(
ift
,
0
);
in6_ifa_put
(
ift
);
in6_dev_put
(
idev
);
out:
...
...
@@ -1247,7 +1247,7 @@ static void addrconf_add_mroute(struct net_device *dev)
rtmsg
.
rtmsg_dst_len
=
8
;
rtmsg
.
rtmsg_metric
=
IP6_RT_PRIO_ADDRCONF
;
rtmsg
.
rtmsg_ifindex
=
dev
->
ifindex
;
rtmsg
.
rtmsg_flags
=
RTF_UP
|
RTF_ADDRCONF
;
rtmsg
.
rtmsg_flags
=
RTF_UP
;
rtmsg
.
rtmsg_type
=
RTMSG_NEWROUTE
;
ip6_route_add
(
&
rtmsg
,
NULL
,
NULL
);
}
...
...
@@ -1274,7 +1274,7 @@ static void addrconf_add_lroute(struct net_device *dev)
struct
in6_addr
addr
;
ipv6_addr_set
(
&
addr
,
htonl
(
0xFE800000
),
0
,
0
,
0
);
addrconf_prefix_route
(
&
addr
,
64
,
dev
,
0
,
RTF_ADDRCONF
);
addrconf_prefix_route
(
&
addr
,
64
,
dev
,
0
,
0
);
}
static
struct
inet6_dev
*
addrconf_add_dev
(
struct
net_device
*
dev
)
...
...
@@ -1367,7 +1367,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len)
}
}
else
if
(
valid_lft
)
{
addrconf_prefix_route
(
&
pinfo
->
prefix
,
pinfo
->
prefix_len
,
dev
,
rt_expires
,
RTF_ADDRCONF
|
RTF_EXPIRES
);
dev
,
rt_expires
,
RTF_ADDRCONF
|
RTF_EXPIRES
|
RTF_PREFIX_RT
);
}
if
(
rt
)
dst_release
(
&
rt
->
u
.
dst
);
...
...
@@ -1413,7 +1413,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len)
}
update_lft
=
create
=
1
;
addrconf_dad_start
(
ifp
);
addrconf_dad_start
(
ifp
,
RTF_ADDRCONF
|
RTF_PREFIX_RT
);
}
if
(
ifp
)
{
...
...
@@ -1586,7 +1586,7 @@ static int inet6_addr_add(int ifindex, struct in6_addr *pfx, int plen)
ifp
=
ipv6_add_addr
(
idev
,
pfx
,
plen
,
scope
,
IFA_F_PERMANENT
);
if
(
!
IS_ERR
(
ifp
))
{
addrconf_dad_start
(
ifp
);
addrconf_dad_start
(
ifp
,
0
);
in6_ifa_put
(
ifp
);
return
0
;
}
...
...
@@ -1761,7 +1761,7 @@ static void addrconf_add_linklocal(struct inet6_dev *idev, struct in6_addr *addr
ifp
=
ipv6_add_addr
(
idev
,
addr
,
64
,
IFA_LINK
,
IFA_F_PERMANENT
);
if
(
!
IS_ERR
(
ifp
))
{
addrconf_dad_start
(
ifp
);
addrconf_dad_start
(
ifp
,
0
);
in6_ifa_put
(
ifp
);
}
}
...
...
@@ -2021,8 +2021,7 @@ static void addrconf_rs_timer(unsigned long data)
memset
(
&
rtmsg
,
0
,
sizeof
(
struct
in6_rtmsg
));
rtmsg
.
rtmsg_type
=
RTMSG_NEWROUTE
;
rtmsg
.
rtmsg_metric
=
IP6_RT_PRIO_ADDRCONF
;
rtmsg
.
rtmsg_flags
=
(
RTF_ALLONLINK
|
RTF_ADDRCONF
|
RTF_DEFAULT
|
RTF_UP
);
rtmsg
.
rtmsg_flags
=
(
RTF_ALLONLINK
|
RTF_DEFAULT
|
RTF_UP
);
rtmsg
.
rtmsg_ifindex
=
ifp
->
idev
->
dev
->
ifindex
;
...
...
@@ -2036,7 +2035,7 @@ static void addrconf_rs_timer(unsigned long data)
/*
* Duplicate Address Detection
*/
static
void
addrconf_dad_start
(
struct
inet6_ifaddr
*
ifp
)
static
void
addrconf_dad_start
(
struct
inet6_ifaddr
*
ifp
,
int
flags
)
{
struct
net_device
*
dev
;
unsigned
long
rand_num
;
...
...
@@ -2046,7 +2045,8 @@ static void addrconf_dad_start(struct inet6_ifaddr *ifp)
addrconf_join_solict
(
dev
,
&
ifp
->
addr
);
if
(
ifp
->
prefix_len
!=
128
&&
(
ifp
->
flags
&
IFA_F_PERMANENT
))
addrconf_prefix_route
(
&
ifp
->
addr
,
ifp
->
prefix_len
,
dev
,
0
,
RTF_ADDRCONF
);
addrconf_prefix_route
(
&
ifp
->
addr
,
ifp
->
prefix_len
,
dev
,
0
,
flags
);
net_srandom
(
ifp
->
addr
.
s6_addr32
[
3
]);
rand_num
=
net_random
()
%
(
ifp
->
idev
->
cnf
.
rtr_solicit_delay
?
:
1
);
...
...
net/ipv6/route.c
View file @
42e8ae0c
...
...
@@ -1459,13 +1459,20 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,
struct
in6_addr
*
src
,
int
iif
,
int
type
,
u32
pid
,
u32
seq
,
struct
nlmsghdr
*
in_nlh
)
struct
nlmsghdr
*
in_nlh
,
int
prefix
)
{
struct
rtmsg
*
rtm
;
struct
nlmsghdr
*
nlh
;
unsigned
char
*
b
=
skb
->
tail
;
struct
rta_cacheinfo
ci
;
if
(
prefix
)
{
/* user wants prefix routes only */
if
(
!
(
rt
->
rt6i_flags
&
RTF_PREFIX_RT
))
{
/* success since this is not a prefix route */
return
1
;
}
}
if
(
!
pid
&&
in_nlh
)
{
pid
=
in_nlh
->
nlmsg_pid
;
}
...
...
@@ -1546,10 +1553,17 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,
static
int
rt6_dump_route
(
struct
rt6_info
*
rt
,
void
*
p_arg
)
{
struct
rt6_rtnl_dump_arg
*
arg
=
(
struct
rt6_rtnl_dump_arg
*
)
p_arg
;
struct
rtmsg
*
rtm
;
int
prefix
;
rtm
=
NLMSG_DATA
(
arg
->
cb
->
nlh
);
if
(
rtm
)
prefix
=
(
rtm
->
rtm_flags
&
RTM_F_PREFIX
)
!=
0
;
else
prefix
=
0
;
return
rt6_fill_node
(
arg
->
skb
,
rt
,
NULL
,
NULL
,
0
,
RTM_NEWROUTE
,
NETLINK_CB
(
arg
->
cb
->
skb
).
pid
,
arg
->
cb
->
nlh
->
nlmsg_seq
,
NULL
);
NULL
,
prefix
);
}
static
int
fib6_dump_node
(
struct
fib6_walker_t
*
w
)
...
...
@@ -1697,7 +1711,7 @@ int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg)
&
fl
.
fl6_dst
,
&
fl
.
fl6_src
,
iif
,
RTM_NEWROUTE
,
NETLINK_CB
(
in_skb
).
pid
,
nlh
->
nlmsg_seq
,
nlh
);
nlh
->
nlmsg_seq
,
nlh
,
0
);
if
(
err
<
0
)
{
err
=
-
EMSGSIZE
;
goto
out_free
;
...
...
@@ -1723,7 +1737,7 @@ void inet6_rt_notify(int event, struct rt6_info *rt, struct nlmsghdr *nlh)
netlink_set_err
(
rtnl
,
0
,
RTMGRP_IPV6_ROUTE
,
ENOBUFS
);
return
;
}
if
(
rt6_fill_node
(
skb
,
rt
,
NULL
,
NULL
,
0
,
event
,
0
,
0
,
nlh
)
<
0
)
{
if
(
rt6_fill_node
(
skb
,
rt
,
NULL
,
NULL
,
0
,
event
,
0
,
0
,
nlh
,
0
)
<
0
)
{
kfree_skb
(
skb
);
netlink_set_err
(
rtnl
,
0
,
RTMGRP_IPV6_ROUTE
,
EINVAL
);
return
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment