diff options
Diffstat (limited to 'net')
| -rw-r--r-- | net/bluetooth/hidp/Kconfig | 2 | ||||
| -rw-r--r-- | net/bridge/br_fdb.c | 12 | ||||
| -rw-r--r-- | net/bridge/br_input.c | 2 | ||||
| -rw-r--r-- | net/bridge/br_stp_if.c | 9 | ||||
| -rw-r--r-- | net/core/datagram.c | 4 | ||||
| -rw-r--r-- | net/dccp/dccp.h | 1 | ||||
| -rw-r--r-- | net/dccp/output.c | 34 | ||||
| -rw-r--r-- | net/ethernet/eth.c | 17 | ||||
| -rw-r--r-- | net/ipv4/fib_frontend.c | 2 | ||||
| -rw-r--r-- | net/ipv4/igmp.c | 5 | ||||
| -rw-r--r-- | net/ipv4/netfilter/arp_tables.c | 201 | ||||
| -rw-r--r-- | net/ipv4/netfilter/ipt_addrtype.c | 2 | ||||
| -rw-r--r-- | net/ipv4/tcp_bic.c | 2 | ||||
| -rw-r--r-- | net/ipv6/addrconf.c | 12 | ||||
| -rw-r--r-- | net/ipv6/mcast.c | 23 | ||||
| -rw-r--r-- | net/ipv6/netfilter/ip6_tables.c | 298 | ||||
| -rw-r--r-- | net/ipv6/netfilter/ip6t_MARK.c | 8 | ||||
| -rw-r--r-- | net/ipv6/route.c | 2 | ||||
| -rw-r--r-- | net/rose/rose_timer.c | 1 | ||||
| -rw-r--r-- | net/sched/Kconfig | 394 | ||||
| -rw-r--r-- | net/sctp/sm_make_chunk.c | 2 | ||||
| -rw-r--r-- | net/sctp/socket.c | 90 | ||||
| -rw-r--r-- | net/sctp/ulpevent.c | 6 | ||||
| -rw-r--r-- | net/sunrpc/auth.c | 15 | ||||
| -rw-r--r-- | net/sunrpc/auth_gss/gss_krb5_crypto.c | 23 | ||||
| -rw-r--r-- | net/sunrpc/sunrpc_syms.c | 2 | ||||
| -rw-r--r-- | net/sunrpc/sysctl.c | 7 | ||||
| -rw-r--r-- | net/sunrpc/xprtsock.c | 9 |
28 files changed, 674 insertions, 511 deletions
diff --git a/net/bluetooth/hidp/Kconfig b/net/bluetooth/hidp/Kconfig index 4e958f7d9418..edfea772fb67 100644 --- a/net/bluetooth/hidp/Kconfig +++ b/net/bluetooth/hidp/Kconfig | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | config BT_HIDP | 1 | config BT_HIDP |
| 2 | tristate "HIDP protocol support" | 2 | tristate "HIDP protocol support" |
| 3 | depends on BT && BT_L2CAP | 3 | depends on BT && BT_L2CAP && (BROKEN || !S390) |
| 4 | select INPUT | 4 | select INPUT |
| 5 | help | 5 | help |
| 6 | HIDP (Human Interface Device Protocol) is a transport layer | 6 | HIDP (Human Interface Device Protocol) is a transport layer |
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c index 24396b914d11..1f08a59b51ea 100644 --- a/net/bridge/br_fdb.c +++ b/net/bridge/br_fdb.c | |||
| @@ -86,8 +86,8 @@ void br_fdb_changeaddr(struct net_bridge_port *p, const unsigned char *newaddr) | |||
| 86 | struct net_bridge_port *op; | 86 | struct net_bridge_port *op; |
| 87 | list_for_each_entry(op, &br->port_list, list) { | 87 | list_for_each_entry(op, &br->port_list, list) { |
| 88 | if (op != p && | 88 | if (op != p && |
| 89 | !memcmp(op->dev->dev_addr, | 89 | !compare_ether_addr(op->dev->dev_addr, |
| 90 | f->addr.addr, ETH_ALEN)) { | 90 | f->addr.addr)) { |
| 91 | f->dst = op; | 91 | f->dst = op; |
| 92 | goto insert; | 92 | goto insert; |
| 93 | } | 93 | } |
| @@ -151,8 +151,8 @@ void br_fdb_delete_by_port(struct net_bridge *br, struct net_bridge_port *p) | |||
| 151 | struct net_bridge_port *op; | 151 | struct net_bridge_port *op; |
| 152 | list_for_each_entry(op, &br->port_list, list) { | 152 | list_for_each_entry(op, &br->port_list, list) { |
| 153 | if (op != p && | 153 | if (op != p && |
| 154 | !memcmp(op->dev->dev_addr, | 154 | !compare_ether_addr(op->dev->dev_addr, |
| 155 | f->addr.addr, ETH_ALEN)) { | 155 | f->addr.addr)) { |
| 156 | f->dst = op; | 156 | f->dst = op; |
| 157 | goto skip_delete; | 157 | goto skip_delete; |
| 158 | } | 158 | } |
| @@ -174,7 +174,7 @@ struct net_bridge_fdb_entry *__br_fdb_get(struct net_bridge *br, | |||
| 174 | struct net_bridge_fdb_entry *fdb; | 174 | struct net_bridge_fdb_entry *fdb; |
| 175 | 175 | ||
| 176 | hlist_for_each_entry_rcu(fdb, h, &br->hash[br_mac_hash(addr)], hlist) { | 176 | hlist_for_each_entry_rcu(fdb, h, &br->hash[br_mac_hash(addr)], hlist) { |
| 177 | if (!memcmp(fdb->addr.addr, addr, ETH_ALEN)) { | 177 | if (!compare_ether_addr(fdb->addr.addr, addr)) { |
| 178 | if (unlikely(has_expired(br, fdb))) | 178 | if (unlikely(has_expired(br, fdb))) |
| 179 | break; | 179 | break; |
| 180 | return fdb; | 180 | return fdb; |
| @@ -264,7 +264,7 @@ static inline struct net_bridge_fdb_entry *fdb_find(struct hlist_head *head, | |||
| 264 | struct net_bridge_fdb_entry *fdb; | 264 | struct net_bridge_fdb_entry *fdb; |
| 265 | 265 | ||
| 266 | hlist_for_each_entry_rcu(fdb, h, head, hlist) { | 266 | hlist_for_each_entry_rcu(fdb, h, head, hlist) { |
| 267 | if (!memcmp(fdb->addr.addr, addr, ETH_ALEN)) | 267 | if (!compare_ether_addr(fdb->addr.addr, addr)) |
| 268 | return fdb; | 268 | return fdb; |
| 269 | } | 269 | } |
| 270 | return NULL; | 270 | return NULL; |
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index 9a45e6279c57..b88220a64cd8 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c | |||
| @@ -128,7 +128,7 @@ int br_handle_frame(struct net_bridge_port *p, struct sk_buff **pskb) | |||
| 128 | dest = eth_hdr(skb)->h_dest; | 128 | dest = eth_hdr(skb)->h_dest; |
| 129 | } | 129 | } |
| 130 | 130 | ||
| 131 | if (!memcmp(p->br->dev->dev_addr, dest, ETH_ALEN)) | 131 | if (!compare_ether_addr(p->br->dev->dev_addr, dest)) |
| 132 | skb->pkt_type = PACKET_HOST; | 132 | skb->pkt_type = PACKET_HOST; |
| 133 | 133 | ||
| 134 | NF_HOOK(PF_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL, | 134 | NF_HOOK(PF_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL, |
diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c index 0da11ff05fa3..ac09b6a23523 100644 --- a/net/bridge/br_stp_if.c +++ b/net/bridge/br_stp_if.c | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | 15 | ||
| 16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
| 17 | #include <linux/smp_lock.h> | 17 | #include <linux/smp_lock.h> |
| 18 | #include <linux/etherdevice.h> | ||
| 18 | 19 | ||
| 19 | #include "br_private.h" | 20 | #include "br_private.h" |
| 20 | #include "br_private_stp.h" | 21 | #include "br_private_stp.h" |
| @@ -133,10 +134,10 @@ static void br_stp_change_bridge_id(struct net_bridge *br, | |||
| 133 | memcpy(br->dev->dev_addr, addr, ETH_ALEN); | 134 | memcpy(br->dev->dev_addr, addr, ETH_ALEN); |
| 134 | 135 | ||
| 135 | list_for_each_entry(p, &br->port_list, list) { | 136 | list_for_each_entry(p, &br->port_list, list) { |
| 136 | if (!memcmp(p->designated_bridge.addr, oldaddr, ETH_ALEN)) | 137 | if (!compare_ether_addr(p->designated_bridge.addr, oldaddr)) |
| 137 | memcpy(p->designated_bridge.addr, addr, ETH_ALEN); | 138 | memcpy(p->designated_bridge.addr, addr, ETH_ALEN); |
| 138 | 139 | ||
| 139 | if (!memcmp(p->designated_root.addr, oldaddr, ETH_ALEN)) | 140 | if (!compare_ether_addr(p->designated_root.addr, oldaddr)) |
| 140 | memcpy(p->designated_root.addr, addr, ETH_ALEN); | 141 | memcpy(p->designated_root.addr, addr, ETH_ALEN); |
| 141 | 142 | ||
| 142 | } | 143 | } |
| @@ -157,12 +158,12 @@ void br_stp_recalculate_bridge_id(struct net_bridge *br) | |||
| 157 | 158 | ||
| 158 | list_for_each_entry(p, &br->port_list, list) { | 159 | list_for_each_entry(p, &br->port_list, list) { |
| 159 | if (addr == br_mac_zero || | 160 | if (addr == br_mac_zero || |
| 160 | memcmp(p->dev->dev_addr, addr, ETH_ALEN) < 0) | 161 | compare_ether_addr(p->dev->dev_addr, addr) < 0) |
| 161 | addr = p->dev->dev_addr; | 162 | addr = p->dev->dev_addr; |
| 162 | 163 | ||
| 163 | } | 164 | } |
| 164 | 165 | ||
| 165 | if (memcmp(br->bridge_id.addr, addr, ETH_ALEN)) | 166 | if (compare_ether_addr(br->bridge_id.addr, addr)) |
| 166 | br_stp_change_bridge_id(br, addr); | 167 | br_stp_change_bridge_id(br, addr); |
| 167 | } | 168 | } |
| 168 | 169 | ||
diff --git a/net/core/datagram.c b/net/core/datagram.c index 81987df536eb..d219435d086c 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c | |||
| @@ -213,6 +213,10 @@ int skb_copy_datagram_iovec(const struct sk_buff *skb, int offset, | |||
| 213 | { | 213 | { |
| 214 | int i, err, fraglen, end = 0; | 214 | int i, err, fraglen, end = 0; |
| 215 | struct sk_buff *next = skb_shinfo(skb)->frag_list; | 215 | struct sk_buff *next = skb_shinfo(skb)->frag_list; |
| 216 | |||
| 217 | if (!len) | ||
| 218 | return 0; | ||
| 219 | |||
| 216 | next_skb: | 220 | next_skb: |
| 217 | fraglen = skb_headlen(skb); | 221 | fraglen = skb_headlen(skb); |
| 218 | i = -1; | 222 | i = -1; |
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h index 5871c027f9dc..f97b85d55ad8 100644 --- a/net/dccp/dccp.h +++ b/net/dccp/dccp.h | |||
| @@ -118,7 +118,6 @@ DECLARE_SNMP_STAT(struct dccp_mib, dccp_statistics); | |||
| 118 | #define DCCP_ADD_STATS_USER(field, val) \ | 118 | #define DCCP_ADD_STATS_USER(field, val) \ |
| 119 | SNMP_ADD_STATS_USER(dccp_statistics, field, val) | 119 | SNMP_ADD_STATS_USER(dccp_statistics, field, val) |
| 120 | 120 | ||
| 121 | extern int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb); | ||
| 122 | extern int dccp_retransmit_skb(struct sock *sk, struct sk_buff *skb); | 121 | extern int dccp_retransmit_skb(struct sock *sk, struct sk_buff *skb); |
| 123 | 122 | ||
| 124 | extern int dccp_send_response(struct sock *sk); | 123 | extern int dccp_send_response(struct sock *sk); |
diff --git a/net/dccp/output.c b/net/dccp/output.c index d59f86f7ceab..74ff87025878 100644 --- a/net/dccp/output.c +++ b/net/dccp/output.c | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | 12 | ||
| 13 | #include <linux/config.h> | 13 | #include <linux/config.h> |
| 14 | #include <linux/dccp.h> | 14 | #include <linux/dccp.h> |
| 15 | #include <linux/kernel.h> | ||
| 15 | #include <linux/skbuff.h> | 16 | #include <linux/skbuff.h> |
| 16 | 17 | ||
| 17 | #include <net/sock.h> | 18 | #include <net/sock.h> |
| @@ -25,13 +26,20 @@ static inline void dccp_event_ack_sent(struct sock *sk) | |||
| 25 | inet_csk_clear_xmit_timer(sk, ICSK_TIME_DACK); | 26 | inet_csk_clear_xmit_timer(sk, ICSK_TIME_DACK); |
| 26 | } | 27 | } |
| 27 | 28 | ||
| 29 | static inline void dccp_skb_entail(struct sock *sk, struct sk_buff *skb) | ||
| 30 | { | ||
| 31 | skb_set_owner_w(skb, sk); | ||
| 32 | WARN_ON(sk->sk_send_head); | ||
| 33 | sk->sk_send_head = skb; | ||
| 34 | } | ||
| 35 | |||
| 28 | /* | 36 | /* |
| 29 | * All SKB's seen here are completely headerless. It is our | 37 | * All SKB's seen here are completely headerless. It is our |
| 30 | * job to build the DCCP header, and pass the packet down to | 38 | * job to build the DCCP header, and pass the packet down to |
| 31 | * IP so it can do the same plus pass the packet off to the | 39 | * IP so it can do the same plus pass the packet off to the |
| 32 | * device. | 40 | * device. |
| 33 | */ | 41 | */ |
| 34 | int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb) | 42 | static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb) |
| 35 | { | 43 | { |
| 36 | if (likely(skb != NULL)) { | 44 | if (likely(skb != NULL)) { |
| 37 | const struct inet_sock *inet = inet_sk(sk); | 45 | const struct inet_sock *inet = inet_sk(sk); |
| @@ -50,10 +58,21 @@ int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb) | |||
| 50 | switch (dcb->dccpd_type) { | 58 | switch (dcb->dccpd_type) { |
| 51 | case DCCP_PKT_DATA: | 59 | case DCCP_PKT_DATA: |
| 52 | set_ack = 0; | 60 | set_ack = 0; |
| 61 | /* fall through */ | ||
| 62 | case DCCP_PKT_DATAACK: | ||
| 53 | break; | 63 | break; |
| 64 | |||
| 54 | case DCCP_PKT_SYNC: | 65 | case DCCP_PKT_SYNC: |
| 55 | case DCCP_PKT_SYNCACK: | 66 | case DCCP_PKT_SYNCACK: |
| 56 | ackno = dcb->dccpd_seq; | 67 | ackno = dcb->dccpd_seq; |
| 68 | /* fall through */ | ||
| 69 | default: | ||
| 70 | /* | ||
| 71 | * Only data packets should come through with skb->sk | ||
| 72 | * set. | ||
| 73 | */ | ||
| 74 | WARN_ON(skb->sk); | ||
| 75 | skb_set_owner_w(skb, sk); | ||
| 57 | break; | 76 | break; |
| 58 | } | 77 | } |
| 59 | 78 | ||
| @@ -63,9 +82,6 @@ int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb) | |||
| 63 | skb->h.raw = skb_push(skb, dccp_header_size); | 82 | skb->h.raw = skb_push(skb, dccp_header_size); |
| 64 | dh = dccp_hdr(skb); | 83 | dh = dccp_hdr(skb); |
| 65 | 84 | ||
| 66 | if (!skb->sk) | ||
| 67 | skb_set_owner_w(skb, sk); | ||
| 68 | |||
| 69 | /* Build DCCP header and checksum it. */ | 85 | /* Build DCCP header and checksum it. */ |
| 70 | memset(dh, 0, dccp_header_size); | 86 | memset(dh, 0, dccp_header_size); |
| 71 | dh->dccph_type = dcb->dccpd_type; | 87 | dh->dccph_type = dcb->dccpd_type; |
| @@ -393,10 +409,8 @@ int dccp_connect(struct sock *sk) | |||
| 393 | 409 | ||
| 394 | DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_REQUEST; | 410 | DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_REQUEST; |
| 395 | skb->csum = 0; | 411 | skb->csum = 0; |
| 396 | skb_set_owner_w(skb, sk); | ||
| 397 | 412 | ||
| 398 | BUG_TRAP(sk->sk_send_head == NULL); | 413 | dccp_skb_entail(sk, skb); |
| 399 | sk->sk_send_head = skb; | ||
| 400 | dccp_transmit_skb(sk, skb_clone(skb, GFP_KERNEL)); | 414 | dccp_transmit_skb(sk, skb_clone(skb, GFP_KERNEL)); |
| 401 | DCCP_INC_STATS(DCCP_MIB_ACTIVEOPENS); | 415 | DCCP_INC_STATS(DCCP_MIB_ACTIVEOPENS); |
| 402 | 416 | ||
| @@ -425,7 +439,6 @@ void dccp_send_ack(struct sock *sk) | |||
| 425 | skb_reserve(skb, MAX_DCCP_HEADER); | 439 | skb_reserve(skb, MAX_DCCP_HEADER); |
| 426 | skb->csum = 0; | 440 | skb->csum = 0; |
| 427 | DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_ACK; | 441 | DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_ACK; |
| 428 | skb_set_owner_w(skb, sk); | ||
| 429 | dccp_transmit_skb(sk, skb); | 442 | dccp_transmit_skb(sk, skb); |
| 430 | } | 443 | } |
| 431 | } | 444 | } |
| @@ -482,7 +495,6 @@ void dccp_send_sync(struct sock *sk, const u64 seq, | |||
| 482 | DCCP_SKB_CB(skb)->dccpd_type = pkt_type; | 495 | DCCP_SKB_CB(skb)->dccpd_type = pkt_type; |
| 483 | DCCP_SKB_CB(skb)->dccpd_seq = seq; | 496 | DCCP_SKB_CB(skb)->dccpd_seq = seq; |
| 484 | 497 | ||
| 485 | skb_set_owner_w(skb, sk); | ||
| 486 | dccp_transmit_skb(sk, skb); | 498 | dccp_transmit_skb(sk, skb); |
| 487 | } | 499 | } |
| 488 | 500 | ||
| @@ -507,10 +519,8 @@ void dccp_send_close(struct sock *sk, const int active) | |||
| 507 | DCCP_SKB_CB(skb)->dccpd_type = dp->dccps_role == DCCP_ROLE_CLIENT ? | 519 | DCCP_SKB_CB(skb)->dccpd_type = dp->dccps_role == DCCP_ROLE_CLIENT ? |
| 508 | DCCP_PKT_CLOSE : DCCP_PKT_CLOSEREQ; | 520 | DCCP_PKT_CLOSE : DCCP_PKT_CLOSEREQ; |
| 509 | 521 | ||
| 510 | skb_set_owner_w(skb, sk); | ||
| 511 | if (active) { | 522 | if (active) { |
| 512 | BUG_TRAP(sk->sk_send_head == NULL); | 523 | dccp_skb_entail(sk, skb); |
| 513 | sk->sk_send_head = skb; | ||
| 514 | dccp_transmit_skb(sk, skb_clone(skb, prio)); | 524 | dccp_transmit_skb(sk, skb_clone(skb, prio)); |
| 515 | } else | 525 | } else |
| 516 | dccp_transmit_skb(sk, skb); | 526 | dccp_transmit_skb(sk, skb); |
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c index 68a5ca866442..e24577367274 100644 --- a/net/ethernet/eth.c +++ b/net/ethernet/eth.c | |||
| @@ -146,19 +146,6 @@ int eth_rebuild_header(struct sk_buff *skb) | |||
| 146 | return 0; | 146 | return 0; |
| 147 | } | 147 | } |
| 148 | 148 | ||
| 149 | static inline unsigned int compare_eth_addr(const unsigned char *__a, const unsigned char *__b) | ||
| 150 | { | ||
| 151 | const unsigned short *dest = (unsigned short *) __a; | ||
| 152 | const unsigned short *devaddr = (unsigned short *) __b; | ||
| 153 | unsigned int res; | ||
| 154 | |||
| 155 | BUILD_BUG_ON(ETH_ALEN != 6); | ||
| 156 | res = ((dest[0] ^ devaddr[0]) | | ||
| 157 | (dest[1] ^ devaddr[1]) | | ||
| 158 | (dest[2] ^ devaddr[2])) != 0; | ||
| 159 | |||
| 160 | return res; | ||
| 161 | } | ||
| 162 | 149 | ||
| 163 | /* | 150 | /* |
| 164 | * Determine the packet's protocol ID. The rule here is that we | 151 | * Determine the packet's protocol ID. The rule here is that we |
| @@ -176,7 +163,7 @@ __be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev) | |||
| 176 | eth = eth_hdr(skb); | 163 | eth = eth_hdr(skb); |
| 177 | 164 | ||
| 178 | if (*eth->h_dest&1) { | 165 | if (*eth->h_dest&1) { |
| 179 | if (!compare_eth_addr(eth->h_dest, dev->broadcast)) | 166 | if (!compare_ether_addr(eth->h_dest, dev->broadcast)) |
| 180 | skb->pkt_type = PACKET_BROADCAST; | 167 | skb->pkt_type = PACKET_BROADCAST; |
| 181 | else | 168 | else |
| 182 | skb->pkt_type = PACKET_MULTICAST; | 169 | skb->pkt_type = PACKET_MULTICAST; |
| @@ -191,7 +178,7 @@ __be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev) | |||
| 191 | */ | 178 | */ |
| 192 | 179 | ||
| 193 | else if(1 /*dev->flags&IFF_PROMISC*/) { | 180 | else if(1 /*dev->flags&IFF_PROMISC*/) { |
| 194 | if (unlikely(compare_eth_addr(eth->h_dest, dev->dev_addr))) | 181 | if (unlikely(compare_ether_addr(eth->h_dest, dev->dev_addr))) |
| 195 | skb->pkt_type = PACKET_OTHERHOST; | 182 | skb->pkt_type = PACKET_OTHERHOST; |
| 196 | } | 183 | } |
| 197 | 184 | ||
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index e61bc7177eb1..990633c09dfe 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c | |||
| @@ -591,7 +591,7 @@ static int fib_inetaddr_event(struct notifier_block *this, unsigned long event, | |||
| 591 | break; | 591 | break; |
| 592 | case NETDEV_DOWN: | 592 | case NETDEV_DOWN: |
| 593 | fib_del_ifaddr(ifa); | 593 | fib_del_ifaddr(ifa); |
| 594 | if (ifa->ifa_dev && ifa->ifa_dev->ifa_list == NULL) { | 594 | if (ifa->ifa_dev->ifa_list == NULL) { |
| 595 | /* Last address was deleted from this interface. | 595 | /* Last address was deleted from this interface. |
| 596 | Disable IP. | 596 | Disable IP. |
| 597 | */ | 597 | */ |
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index 8b6d3939e1e6..c6247fc84060 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c | |||
| @@ -1908,8 +1908,11 @@ int ip_mc_msfilter(struct sock *sk, struct ip_msfilter *msf, int ifindex) | |||
| 1908 | sock_kfree_s(sk, newpsl, IP_SFLSIZE(newpsl->sl_max)); | 1908 | sock_kfree_s(sk, newpsl, IP_SFLSIZE(newpsl->sl_max)); |
| 1909 | goto done; | 1909 | goto done; |
| 1910 | } | 1910 | } |
| 1911 | } else | 1911 | } else { |
| 1912 | newpsl = NULL; | 1912 | newpsl = NULL; |
| 1913 | (void) ip_mc_add_src(in_dev, &msf->imsf_multiaddr, | ||
| 1914 | msf->imsf_fmode, 0, NULL, 0); | ||
| 1915 | } | ||
| 1913 | psl = pmc->sflist; | 1916 | psl = pmc->sflist; |
| 1914 | if (psl) { | 1917 | if (psl) { |
| 1915 | (void) ip_mc_del_src(in_dev, &msf->imsf_multiaddr, pmc->sfmode, | 1918 | (void) ip_mc_del_src(in_dev, &msf->imsf_multiaddr, pmc->sfmode, |
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index a7969286e6e7..3c2e9639bba6 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c | |||
| @@ -347,58 +347,106 @@ unsigned int arpt_do_table(struct sk_buff **pskb, | |||
| 347 | return verdict; | 347 | return verdict; |
| 348 | } | 348 | } |
| 349 | 349 | ||
| 350 | static inline void *find_inlist_lock_noload(struct list_head *head, | 350 | /* |
| 351 | const char *name, | 351 | * These are weird, but module loading must not be done with mutex |
| 352 | int *error, | 352 | * held (since they will register), and we have to have a single |
| 353 | struct semaphore *mutex) | 353 | * function to use try_then_request_module(). |
| 354 | */ | ||
| 355 | |||
| 356 | /* Find table by name, grabs mutex & ref. Returns ERR_PTR() on error. */ | ||
| 357 | static inline struct arpt_table *find_table_lock(const char *name) | ||
| 354 | { | 358 | { |
| 355 | void *ret; | 359 | struct arpt_table *t; |
| 356 | 360 | ||
| 357 | *error = down_interruptible(mutex); | 361 | if (down_interruptible(&arpt_mutex) != 0) |
| 358 | if (*error != 0) | 362 | return ERR_PTR(-EINTR); |
| 359 | return NULL; | ||
| 360 | 363 | ||
| 361 | ret = list_named_find(head, name); | 364 | list_for_each_entry(t, &arpt_tables, list) |
| 362 | if (!ret) { | 365 | if (strcmp(t->name, name) == 0 && try_module_get(t->me)) |
| 363 | *error = -ENOENT; | 366 | return t; |
| 364 | up(mutex); | 367 | up(&arpt_mutex); |
| 365 | } | 368 | return NULL; |
| 366 | return ret; | ||
| 367 | } | 369 | } |
| 368 | 370 | ||
| 369 | #ifndef CONFIG_KMOD | 371 | |
| 370 | #define find_inlist_lock(h,n,p,e,m) find_inlist_lock_noload((h),(n),(e),(m)) | 372 | /* Find target, grabs ref. Returns ERR_PTR() on error. */ |
| 371 | #else | 373 | static inline struct arpt_target *find_target(const char *name, u8 revision) |
| 372 | static void * | ||
| 373 | find_inlist_lock(struct list_head *head, | ||
| 374 | const char *name, | ||
| 375 | const char *prefix, | ||
| 376 | int *error, | ||
| 377 | struct semaphore *mutex) | ||
| 378 | { | 374 | { |
| 379 | void *ret; | 375 | struct arpt_target *t; |
| 376 | int err = 0; | ||
| 380 | 377 | ||
| 381 | ret = find_inlist_lock_noload(head, name, error, mutex); | 378 | if (down_interruptible(&arpt_mutex) != 0) |
| 382 | if (!ret) { | 379 | return ERR_PTR(-EINTR); |
| 383 | duprintf("find_inlist: loading `%s%s'.\n", prefix, name); | 380 | |
| 384 | request_module("%s%s", prefix, name); | 381 | list_for_each_entry(t, &arpt_target, list) { |
| 385 | ret = find_inlist_lock_noload(head, name, error, mutex); | 382 | if (strcmp(t->name, name) == 0) { |
| 383 | if (t->revision == revision) { | ||
| 384 | if (try_module_get(t->me)) { | ||
| 385 | up(&arpt_mutex); | ||
| 386 | return t; | ||
| 387 | } | ||
| 388 | } else | ||
| 389 | err = -EPROTOTYPE; /* Found something. */ | ||
| 390 | } | ||
| 386 | } | 391 | } |
| 392 | up(&arpt_mutex); | ||
| 393 | return ERR_PTR(err); | ||
| 394 | } | ||
| 387 | 395 | ||
| 388 | return ret; | 396 | struct arpt_target *arpt_find_target(const char *name, u8 revision) |
| 397 | { | ||
| 398 | struct arpt_target *target; | ||
| 399 | |||
| 400 | target = try_then_request_module(find_target(name, revision), | ||
| 401 | "arpt_%s", name); | ||
| 402 | if (IS_ERR(target) || !target) | ||
| 403 | return NULL; | ||
| 404 | return target; | ||
| 389 | } | 405 | } |
| 390 | #endif | ||
| 391 | 406 | ||
| 392 | static inline struct arpt_table *arpt_find_table_lock(const char *name, int *error, struct semaphore *mutex) | 407 | static int target_revfn(const char *name, u8 revision, int *bestp) |
| 393 | { | 408 | { |
| 394 | return find_inlist_lock(&arpt_tables, name, "arptable_", error, mutex); | 409 | struct arpt_target *t; |
| 410 | int have_rev = 0; | ||
| 411 | |||
| 412 | list_for_each_entry(t, &arpt_target, list) { | ||
| 413 | if (strcmp(t->name, name) == 0) { | ||
| 414 | if (t->revision > *bestp) | ||
| 415 | *bestp = t->revision; | ||
| 416 | if (t->revision == revision) | ||
| 417 | have_rev =1; | ||
| 418 | } | ||
| 419 | } | ||
| 420 | return have_rev; | ||
| 395 | } | 421 | } |
| 396 | 422 | ||
| 397 | static struct arpt_target *arpt_find_target_lock(const char *name, int *error, struct semaphore *mutex) | 423 | /* Returns true or false (if no such extension at all) */ |
| 424 | static inline int find_revision(const char *name, u8 revision, | ||
| 425 | int (*revfn)(const char *, u8, int *), | ||
| 426 | int *err) | ||
| 398 | { | 427 | { |
| 399 | return find_inlist_lock(&arpt_target, name, "arpt_", error, mutex); | 428 | int have_rev, best = -1; |
| 429 | |||
| 430 | if (down_interruptible(&arpt_mutex) != 0) { | ||
| 431 | *err = -EINTR; | ||
| 432 | return 1; | ||
| 433 | } | ||
| 434 | have_rev = revfn(name, revision, &best); | ||
| 435 | up(&arpt_mutex); | ||
| 436 | |||
| 437 | /* Nothing at all? Return 0 to try loading module. */ | ||
| 438 | if (best == -1) { | ||
| 439 | *err = -ENOENT; | ||
| 440 | return 0; | ||
| 441 | } | ||
| 442 | |||
| 443 | *err = best; | ||
| 444 | if (!have_rev) | ||
| 445 | *err = -EPROTONOSUPPORT; | ||
| 446 | return 1; | ||
| 400 | } | 447 | } |
| 401 | 448 | ||
| 449 | |||
| 402 | /* All zeroes == unconditional rule. */ | 450 | /* All zeroes == unconditional rule. */ |
| 403 | static inline int unconditional(const struct arpt_arp *arp) | 451 | static inline int unconditional(const struct arpt_arp *arp) |
| 404 | { | 452 | { |
| @@ -544,17 +592,15 @@ static inline int check_entry(struct arpt_entry *e, const char *name, unsigned i | |||
| 544 | } | 592 | } |
| 545 | 593 | ||
| 546 | t = arpt_get_target(e); | 594 | t = arpt_get_target(e); |
| 547 | target = arpt_find_target_lock(t->u.user.name, &ret, &arpt_mutex); | 595 | target = try_then_request_module(find_target(t->u.user.name, |
| 548 | if (!target) { | 596 | t->u.user.revision), |
| 597 | "arpt_%s", t->u.user.name); | ||
| 598 | if (IS_ERR(target) || !target) { | ||
| 549 | duprintf("check_entry: `%s' not found\n", t->u.user.name); | 599 | duprintf("check_entry: `%s' not found\n", t->u.user.name); |
| 600 | ret = target ? PTR_ERR(target) : -ENOENT; | ||
| 550 | goto out; | 601 | goto out; |
| 551 | } | 602 | } |
| 552 | if (!try_module_get((target->me))) { | ||
| 553 | ret = -ENOENT; | ||
| 554 | goto out_unlock; | ||
| 555 | } | ||
| 556 | t->u.kernel.target = target; | 603 | t->u.kernel.target = target; |
| 557 | up(&arpt_mutex); | ||
| 558 | 604 | ||
| 559 | if (t->u.kernel.target == &arpt_standard_target) { | 605 | if (t->u.kernel.target == &arpt_standard_target) { |
| 560 | if (!standard_check(t, size)) { | 606 | if (!standard_check(t, size)) { |
| @@ -576,8 +622,6 @@ static inline int check_entry(struct arpt_entry *e, const char *name, unsigned i | |||
| 576 | (*i)++; | 622 | (*i)++; |
| 577 | return 0; | 623 | return 0; |
| 578 | 624 | ||
| 579 | out_unlock: | ||
| 580 | up(&arpt_mutex); | ||
| 581 | out: | 625 | out: |
| 582 | return ret; | 626 | return ret; |
| 583 | } | 627 | } |
| @@ -846,8 +890,8 @@ static int get_entries(const struct arpt_get_entries *entries, | |||
| 846 | int ret; | 890 | int ret; |
| 847 | struct arpt_table *t; | 891 | struct arpt_table *t; |
| 848 | 892 | ||
| 849 | t = arpt_find_table_lock(entries->name, &ret, &arpt_mutex); | 893 | t = find_table_lock(entries->name); |
| 850 | if (t) { | 894 | if (t || !IS_ERR(t)) { |
| 851 | duprintf("t->private->number = %u\n", | 895 | duprintf("t->private->number = %u\n", |
| 852 | t->private->number); | 896 | t->private->number); |
| 853 | if (entries->size == t->private->size) | 897 | if (entries->size == t->private->size) |
| @@ -859,10 +903,10 @@ static int get_entries(const struct arpt_get_entries *entries, | |||
| 859 | entries->size); | 903 | entries->size); |
| 860 | ret = -EINVAL; | 904 | ret = -EINVAL; |
| 861 | } | 905 | } |
| 906 | module_put(t->me); | ||
| 862 | up(&arpt_mutex); | 907 | up(&arpt_mutex); |
| 863 | } else | 908 | } else |
| 864 | duprintf("get_entries: Can't find %s!\n", | 909 | ret = t ? PTR_ERR(t) : -ENOENT; |
| 865 | entries->name); | ||
| 866 | 910 | ||
| 867 | return ret; | 911 | return ret; |
| 868 | } | 912 | } |
| @@ -913,22 +957,19 @@ static int do_replace(void __user *user, unsigned int len) | |||
| 913 | 957 | ||
| 914 | duprintf("arp_tables: Translated table\n"); | 958 | duprintf("arp_tables: Translated table\n"); |
| 915 | 959 | ||
| 916 | t = arpt_find_table_lock(tmp.name, &ret, &arpt_mutex); | 960 | t = try_then_request_module(find_table_lock(tmp.name), |
| 917 | if (!t) | 961 | "arptable_%s", tmp.name); |
| 962 | if (!t || IS_ERR(t)) { | ||
| 963 | ret = t ? PTR_ERR(t) : -ENOENT; | ||
| 918 | goto free_newinfo_counters_untrans; | 964 | goto free_newinfo_counters_untrans; |
| 965 | } | ||
| 919 | 966 | ||
| 920 | /* You lied! */ | 967 | /* You lied! */ |
| 921 | if (tmp.valid_hooks != t->valid_hooks) { | 968 | if (tmp.valid_hooks != t->valid_hooks) { |
| 922 | duprintf("Valid hook crap: %08X vs %08X\n", | 969 | duprintf("Valid hook crap: %08X vs %08X\n", |
| 923 | tmp.valid_hooks, t->valid_hooks); | 970 | tmp.valid_hooks, t->valid_hooks); |
| 924 | ret = -EINVAL; | 971 | ret = -EINVAL; |
| 925 | goto free_newinfo_counters_untrans_unlock; | 972 | goto put_module; |
| 926 | } | ||
| 927 | |||
| 928 | /* Get a reference in advance, we're not allowed fail later */ | ||
| 929 | if (!try_module_get(t->me)) { | ||
| 930 | ret = -EBUSY; | ||
| 931 | goto free_newinfo_counters_untrans_unlock; | ||
| 932 | } | 973 | } |
| 933 | 974 | ||
| 934 | oldinfo = replace_table(t, tmp.num_counters, newinfo, &ret); | 975 | oldinfo = replace_table(t, tmp.num_counters, newinfo, &ret); |
| @@ -959,7 +1000,6 @@ static int do_replace(void __user *user, unsigned int len) | |||
| 959 | 1000 | ||
| 960 | put_module: | 1001 | put_module: |
| 961 | module_put(t->me); | 1002 | module_put(t->me); |
| 962 | free_newinfo_counters_untrans_unlock: | ||
| 963 | up(&arpt_mutex); | 1003 | up(&arpt_mutex); |
| 964 | free_newinfo_counters_untrans: | 1004 | free_newinfo_counters_untrans: |
| 965 | ARPT_ENTRY_ITERATE(newinfo->entries, newinfo->size, cleanup_entry, NULL); | 1005 | ARPT_ENTRY_ITERATE(newinfo->entries, newinfo->size, cleanup_entry, NULL); |
| @@ -989,7 +1029,7 @@ static int do_add_counters(void __user *user, unsigned int len) | |||
| 989 | unsigned int i; | 1029 | unsigned int i; |
| 990 | struct arpt_counters_info tmp, *paddc; | 1030 | struct arpt_counters_info tmp, *paddc; |
| 991 | struct arpt_table *t; | 1031 | struct arpt_table *t; |
| 992 | int ret; | 1032 | int ret = 0; |
| 993 | 1033 | ||
| 994 | if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) | 1034 | if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) |
| 995 | return -EFAULT; | 1035 | return -EFAULT; |
| @@ -1006,9 +1046,11 @@ static int do_add_counters(void __user *user, unsigned int len) | |||
| 1006 | goto free; | 1046 | goto free; |
| 1007 | } | 1047 | } |
| 1008 | 1048 | ||
| 1009 | t = arpt_find_table_lock(tmp.name, &ret, &arpt_mutex); | 1049 | t = find_table_lock(tmp.name); |
| 1010 | if (!t) | 1050 | if (!t || IS_ERR(t)) { |
| 1051 | ret = t ? PTR_ERR(t) : -ENOENT; | ||
| 1011 | goto free; | 1052 | goto free; |
| 1053 | } | ||
| 1012 | 1054 | ||
| 1013 | write_lock_bh(&t->lock); | 1055 | write_lock_bh(&t->lock); |
| 1014 | if (t->private->number != paddc->num_counters) { | 1056 | if (t->private->number != paddc->num_counters) { |
| @@ -1025,6 +1067,7 @@ static int do_add_counters(void __user *user, unsigned int len) | |||
| 1025 | unlock_up_free: | 1067 | unlock_up_free: |
| 1026 | write_unlock_bh(&t->lock); | 1068 | write_unlock_bh(&t->lock); |
| 1027 | up(&arpt_mutex); | 1069 | up(&arpt_mutex); |
| 1070 | module_put(t->me); | ||
| 1028 | free: | 1071 | free: |
| 1029 | vfree(paddc); | 1072 | vfree(paddc); |
| 1030 | 1073 | ||
| @@ -1079,8 +1122,10 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len | |||
| 1079 | break; | 1122 | break; |
| 1080 | } | 1123 | } |
| 1081 | name[ARPT_TABLE_MAXNAMELEN-1] = '\0'; | 1124 | name[ARPT_TABLE_MAXNAMELEN-1] = '\0'; |
| 1082 | t = arpt_find_table_lock(name, &ret, &arpt_mutex); | 1125 | |
| 1083 | if (t) { | 1126 | t = try_then_request_module(find_table_lock(name), |
| 1127 | "arptable_%s", name); | ||
| 1128 | if (t && !IS_ERR(t)) { | ||
| 1084 | struct arpt_getinfo info; | 1129 | struct arpt_getinfo info; |
| 1085 | 1130 | ||
| 1086 | info.valid_hooks = t->valid_hooks; | 1131 | info.valid_hooks = t->valid_hooks; |
| @@ -1096,9 +1141,10 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len | |||
| 1096 | ret = -EFAULT; | 1141 | ret = -EFAULT; |
| 1097 | else | 1142 | else |
| 1098 | ret = 0; | 1143 | ret = 0; |
| 1099 | |||
| 1100 | up(&arpt_mutex); | 1144 | up(&arpt_mutex); |
| 1101 | } | 1145 | module_put(t->me); |
| 1146 | } else | ||
| 1147 | ret = t ? PTR_ERR(t) : -ENOENT; | ||
| 1102 | } | 1148 | } |
| 1103 | break; | 1149 | break; |
| 1104 | 1150 | ||
| @@ -1119,6 +1165,24 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len | |||
| 1119 | break; | 1165 | break; |
| 1120 | } | 1166 | } |
| 1121 | 1167 | ||
| 1168 | case ARPT_SO_GET_REVISION_TARGET: { | ||
| 1169 | struct arpt_get_revision rev; | ||
| 1170 | |||
| 1171 | if (*len != sizeof(rev)) { | ||
| 1172 | ret = -EINVAL; | ||
| 1173 | break; | ||
| 1174 | } | ||
| 1175 | if (copy_from_user(&rev, user, sizeof(rev)) != 0) { | ||
| 1176 | ret = -EFAULT; | ||
| 1177 | break; | ||
| 1178 | } | ||
| 1179 | |||
| 1180 | try_then_request_module(find_revision(rev.name, rev.revision, | ||
| 1181 | target_revfn, &ret), | ||
| 1182 | "arpt_%s", rev.name); | ||
| 1183 | break; | ||
| 1184 | } | ||
| 1185 | |||
| 1122 | default: | 1186 | default: |
| 1123 | duprintf("do_arpt_get_ctl: unknown request %i\n", cmd); | 1187 | duprintf("do_arpt_get_ctl: unknown request %i\n", cmd); |
| 1124 | ret = -EINVAL; | 1188 | ret = -EINVAL; |
| @@ -1136,12 +1200,9 @@ int arpt_register_target(struct arpt_target *target) | |||
| 1136 | if (ret != 0) | 1200 | if (ret != 0) |
| 1137 | return ret; | 1201 | return ret; |
| 1138 | 1202 | ||
| 1139 | if (!list_named_insert(&arpt_target, target)) { | 1203 | list_add(&target->list, &arpt_target); |
| 1140 | duprintf("arpt_register_target: `%s' already in list!\n", | ||
| 1141 | target->name); | ||
| 1142 | ret = -EINVAL; | ||
| 1143 | } | ||
| 1144 | up(&arpt_mutex); | 1204 | up(&arpt_mutex); |
| 1205 | |||
| 1145 | return ret; | 1206 | return ret; |
| 1146 | } | 1207 | } |
| 1147 | 1208 | ||
diff --git a/net/ipv4/netfilter/ipt_addrtype.c b/net/ipv4/netfilter/ipt_addrtype.c index f5909a4c3fc7..e19c2a52d00c 100644 --- a/net/ipv4/netfilter/ipt_addrtype.c +++ b/net/ipv4/netfilter/ipt_addrtype.c | |||
| @@ -48,7 +48,7 @@ static int checkentry(const char *tablename, const struct ipt_ip *ip, | |||
| 48 | unsigned int hook_mask) | 48 | unsigned int hook_mask) |
| 49 | { | 49 | { |
| 50 | if (matchsize != IPT_ALIGN(sizeof(struct ipt_addrtype_info))) { | 50 | if (matchsize != IPT_ALIGN(sizeof(struct ipt_addrtype_info))) { |
| 51 | printk(KERN_ERR "ipt_addrtype: invalid size (%u != %Zu)\n.", | 51 | printk(KERN_ERR "ipt_addrtype: invalid size (%u != %Zu)\n", |
| 52 | matchsize, IPT_ALIGN(sizeof(struct ipt_addrtype_info))); | 52 | matchsize, IPT_ALIGN(sizeof(struct ipt_addrtype_info))); |
| 53 | return 0; | 53 | return 0; |
| 54 | } | 54 | } |
diff --git a/net/ipv4/tcp_bic.c b/net/ipv4/tcp_bic.c index 6d80e063c187..ae35e0609047 100644 --- a/net/ipv4/tcp_bic.c +++ b/net/ipv4/tcp_bic.c | |||
| @@ -27,7 +27,7 @@ | |||
| 27 | */ | 27 | */ |
| 28 | 28 | ||
| 29 | static int fast_convergence = 1; | 29 | static int fast_convergence = 1; |
| 30 | static int max_increment = 32; | 30 | static int max_increment = 16; |
| 31 | static int low_window = 14; | 31 | static int low_window = 14; |
| 32 | static int beta = 819; /* = 819/1024 (BICTCP_BETA_SCALE) */ | 32 | static int beta = 819; /* = 819/1024 (BICTCP_BETA_SCALE) */ |
| 33 | static int low_utilization_threshold = 153; | 33 | static int low_utilization_threshold = 153; |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index a970b4727ce8..2c5f57299d63 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
| @@ -75,7 +75,7 @@ | |||
| 75 | #ifdef CONFIG_IPV6_PRIVACY | 75 | #ifdef CONFIG_IPV6_PRIVACY |
| 76 | #include <linux/random.h> | 76 | #include <linux/random.h> |
| 77 | #include <linux/crypto.h> | 77 | #include <linux/crypto.h> |
| 78 | #include <asm/scatterlist.h> | 78 | #include <linux/scatterlist.h> |
| 79 | #endif | 79 | #endif |
| 80 | 80 | ||
| 81 | #include <asm/uaccess.h> | 81 | #include <asm/uaccess.h> |
| @@ -1217,12 +1217,8 @@ static int __ipv6_regen_rndid(struct inet6_dev *idev) | |||
| 1217 | struct net_device *dev; | 1217 | struct net_device *dev; |
| 1218 | struct scatterlist sg[2]; | 1218 | struct scatterlist sg[2]; |
| 1219 | 1219 | ||
| 1220 | sg[0].page = virt_to_page(idev->entropy); | 1220 | sg_set_buf(&sg[0], idev->entropy, 8); |
| 1221 | sg[0].offset = offset_in_page(idev->entropy); | 1221 | sg_set_buf(&sg[1], idev->work_eui64, 8); |
| 1222 | sg[0].length = 8; | ||
| 1223 | sg[1].page = virt_to_page(idev->work_eui64); | ||
| 1224 | sg[1].offset = offset_in_page(idev->work_eui64); | ||
| 1225 | sg[1].length = 8; | ||
| 1226 | 1222 | ||
| 1227 | dev = idev->dev; | 1223 | dev = idev->dev; |
| 1228 | 1224 | ||
| @@ -2167,7 +2163,7 @@ static int addrconf_ifdown(struct net_device *dev, int how) | |||
| 2167 | 2163 | ||
| 2168 | /* Step 5: netlink notification of this interface */ | 2164 | /* Step 5: netlink notification of this interface */ |
| 2169 | idev->tstamp = jiffies; | 2165 | idev->tstamp = jiffies; |
| 2170 | inet6_ifinfo_notify(RTM_NEWLINK, idev); | 2166 | inet6_ifinfo_notify(RTM_DELLINK, idev); |
| 2171 | 2167 | ||
| 2172 | /* Shot the device (if unregistered) */ | 2168 | /* Shot the device (if unregistered) */ |
| 2173 | 2169 | ||
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index c4f2a0ef7489..f15e04ad026e 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c | |||
| @@ -545,8 +545,10 @@ int ip6_mc_msfilter(struct sock *sk, struct group_filter *gsf) | |||
| 545 | sock_kfree_s(sk, newpsl, IP6_SFLSIZE(newpsl->sl_max)); | 545 | sock_kfree_s(sk, newpsl, IP6_SFLSIZE(newpsl->sl_max)); |
| 546 | goto done; | 546 | goto done; |
| 547 | } | 547 | } |
| 548 | } else | 548 | } else { |
| 549 | newpsl = NULL; | 549 | newpsl = NULL; |
| 550 | (void) ip6_mc_add_src(idev, group, gsf->gf_fmode, 0, NULL, 0); | ||
| 551 | } | ||
| 550 | psl = pmc->sflist; | 552 | psl = pmc->sflist; |
| 551 | if (psl) { | 553 | if (psl) { |
| 552 | (void) ip6_mc_del_src(idev, group, pmc->sfmode, | 554 | (void) ip6_mc_del_src(idev, group, pmc->sfmode, |
| @@ -1087,7 +1089,7 @@ static void mld_marksources(struct ifmcaddr6 *pmc, int nsrcs, | |||
| 1087 | 1089 | ||
| 1088 | int igmp6_event_query(struct sk_buff *skb) | 1090 | int igmp6_event_query(struct sk_buff *skb) |
| 1089 | { | 1091 | { |
| 1090 | struct mld2_query *mlh2 = (struct mld2_query *) skb->h.raw; | 1092 | struct mld2_query *mlh2 = NULL; |
| 1091 | struct ifmcaddr6 *ma; | 1093 | struct ifmcaddr6 *ma; |
| 1092 | struct in6_addr *group; | 1094 | struct in6_addr *group; |
| 1093 | unsigned long max_delay; | 1095 | unsigned long max_delay; |
| @@ -1140,6 +1142,13 @@ int igmp6_event_query(struct sk_buff *skb) | |||
| 1140 | /* clear deleted report items */ | 1142 | /* clear deleted report items */ |
| 1141 | mld_clear_delrec(idev); | 1143 | mld_clear_delrec(idev); |
| 1142 | } else if (len >= 28) { | 1144 | } else if (len >= 28) { |
| 1145 | int srcs_offset = sizeof(struct mld2_query) - | ||
| 1146 | sizeof(struct icmp6hdr); | ||
| 1147 | if (!pskb_may_pull(skb, srcs_offset)) { | ||
| 1148 | in6_dev_put(idev); | ||
| 1149 | return -EINVAL; | ||
| 1150 | } | ||
| 1151 | mlh2 = (struct mld2_query *) skb->h.raw; | ||
| 1143 | max_delay = (MLDV2_MRC(ntohs(mlh2->mrc))*HZ)/1000; | 1152 | max_delay = (MLDV2_MRC(ntohs(mlh2->mrc))*HZ)/1000; |
| 1144 | if (!max_delay) | 1153 | if (!max_delay) |
| 1145 | max_delay = 1; | 1154 | max_delay = 1; |
| @@ -1156,7 +1165,15 @@ int igmp6_event_query(struct sk_buff *skb) | |||
| 1156 | return 0; | 1165 | return 0; |
| 1157 | } | 1166 | } |
| 1158 | /* mark sources to include, if group & source-specific */ | 1167 | /* mark sources to include, if group & source-specific */ |
| 1159 | mark = mlh2->nsrcs != 0; | 1168 | if (mlh2->nsrcs != 0) { |
| 1169 | if (!pskb_may_pull(skb, srcs_offset + | ||
| 1170 | mlh2->nsrcs * sizeof(struct in6_addr))) { | ||
| 1171 | in6_dev_put(idev); | ||
| 1172 | return -EINVAL; | ||
| 1173 | } | ||
| 1174 | mlh2 = (struct mld2_query *) skb->h.raw; | ||
| 1175 | mark = 1; | ||
| 1176 | } | ||
| 1160 | } else { | 1177 | } else { |
| 1161 | in6_dev_put(idev); | 1178 | in6_dev_put(idev); |
| 1162 | return -EINVAL; | 1179 | return -EINVAL; |
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 21deec25a12b..7d492226c16e 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * Packet matching code. | 2 | * Packet matching code. |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling | 4 | * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling |
| 5 | * Copyright (C) 2000-2002 Netfilter core team <coreteam@netfilter.org> | 5 | * Copyright (C) 2000-2005 Netfilter Core Team <coreteam@netfilter.org> |
| 6 | * | 6 | * |
| 7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
| 8 | * it under the terms of the GNU General Public License version 2 as | 8 | * it under the terms of the GNU General Public License version 2 as |
| @@ -23,7 +23,6 @@ | |||
| 23 | #include <linux/tcp.h> | 23 | #include <linux/tcp.h> |
| 24 | #include <linux/udp.h> | 24 | #include <linux/udp.h> |
| 25 | #include <linux/icmpv6.h> | 25 | #include <linux/icmpv6.h> |
| 26 | #include <net/ip.h> | ||
| 27 | #include <net/ipv6.h> | 26 | #include <net/ipv6.h> |
| 28 | #include <asm/uaccess.h> | 27 | #include <asm/uaccess.h> |
| 29 | #include <asm/semaphore.h> | 28 | #include <asm/semaphore.h> |
| @@ -80,13 +79,12 @@ static DECLARE_MUTEX(ip6t_mutex); | |||
| 80 | #define inline | 79 | #define inline |
| 81 | #endif | 80 | #endif |
| 82 | 81 | ||
| 83 | /* Locking is simple: we assume at worst case there will be one packet | 82 | /* |
| 84 | in user context and one from bottom halves (or soft irq if Alexey's | ||
| 85 | softnet patch was applied). | ||
| 86 | |||
| 87 | We keep a set of rules for each CPU, so we can avoid write-locking | 83 | We keep a set of rules for each CPU, so we can avoid write-locking |
| 88 | them; doing a readlock_bh() stops packets coming through if we're | 84 | them in the softirq when updating the counters and therefore |
| 89 | in user context. | 85 | only need to read-lock in the softirq; doing a write_lock_bh() in user |
| 86 | context stops packets coming through and allows user context to read | ||
| 87 | the counters or update the rules. | ||
| 90 | 88 | ||
| 91 | To be cache friendly on SMP, we arrange them like so: | 89 | To be cache friendly on SMP, we arrange them like so: |
| 92 | [ n-entries ] | 90 | [ n-entries ] |
| @@ -356,7 +354,7 @@ ip6t_do_table(struct sk_buff **pskb, | |||
| 356 | struct ip6t_table *table, | 354 | struct ip6t_table *table, |
| 357 | void *userdata) | 355 | void *userdata) |
| 358 | { | 356 | { |
| 359 | static const char nulldevname[IFNAMSIZ]; | 357 | static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long)))); |
| 360 | int offset = 0; | 358 | int offset = 0; |
| 361 | unsigned int protoff = 0; | 359 | unsigned int protoff = 0; |
| 362 | int hotdrop = 0; | 360 | int hotdrop = 0; |
| @@ -369,7 +367,6 @@ ip6t_do_table(struct sk_buff **pskb, | |||
| 369 | /* Initialization */ | 367 | /* Initialization */ |
| 370 | indev = in ? in->name : nulldevname; | 368 | indev = in ? in->name : nulldevname; |
| 371 | outdev = out ? out->name : nulldevname; | 369 | outdev = out ? out->name : nulldevname; |
| 372 | |||
| 373 | /* We handle fragments by dealing with the first fragment as | 370 | /* We handle fragments by dealing with the first fragment as |
| 374 | * if it was a normal packet. All other fragments are treated | 371 | * if it was a normal packet. All other fragments are treated |
| 375 | * normally, except that they will NEVER match rules that ask | 372 | * normally, except that they will NEVER match rules that ask |
| @@ -497,75 +494,145 @@ ip6t_do_table(struct sk_buff **pskb, | |||
| 497 | #endif | 494 | #endif |
| 498 | } | 495 | } |
| 499 | 496 | ||
| 500 | /* If it succeeds, returns element and locks mutex */ | 497 | /* |
| 501 | static inline void * | 498 | * These are weird, but module loading must not be done with mutex |
| 502 | find_inlist_lock_noload(struct list_head *head, | 499 | * held (since they will register), and we have to have a single |
| 503 | const char *name, | 500 | * function to use try_then_request_module(). |
| 504 | int *error, | 501 | */ |
| 505 | struct semaphore *mutex) | 502 | |
| 503 | /* Find table by name, grabs mutex & ref. Returns ERR_PTR() on error. */ | ||
| 504 | static inline struct ip6t_table *find_table_lock(const char *name) | ||
| 506 | { | 505 | { |
| 507 | void *ret; | 506 | struct ip6t_table *t; |
| 508 | 507 | ||
| 509 | #if 1 | 508 | if (down_interruptible(&ip6t_mutex) != 0) |
| 510 | duprintf("find_inlist: searching for `%s' in %s.\n", | 509 | return ERR_PTR(-EINTR); |
| 511 | name, head == &ip6t_target ? "ip6t_target" | ||
| 512 | : head == &ip6t_match ? "ip6t_match" | ||
| 513 | : head == &ip6t_tables ? "ip6t_tables" : "UNKNOWN"); | ||
| 514 | #endif | ||
| 515 | 510 | ||
| 516 | *error = down_interruptible(mutex); | 511 | list_for_each_entry(t, &ip6t_tables, list) |
| 517 | if (*error != 0) | 512 | if (strcmp(t->name, name) == 0 && try_module_get(t->me)) |
| 518 | return NULL; | 513 | return t; |
| 514 | up(&ip6t_mutex); | ||
| 515 | return NULL; | ||
| 516 | } | ||
| 517 | |||
| 518 | /* Find match, grabs ref. Returns ERR_PTR() on error. */ | ||
| 519 | static inline struct ip6t_match *find_match(const char *name, u8 revision) | ||
| 520 | { | ||
| 521 | struct ip6t_match *m; | ||
| 522 | int err = 0; | ||
| 519 | 523 | ||
| 520 | ret = list_named_find(head, name); | 524 | if (down_interruptible(&ip6t_mutex) != 0) |
| 521 | if (!ret) { | 525 | return ERR_PTR(-EINTR); |
| 522 | *error = -ENOENT; | 526 | |
| 523 | up(mutex); | 527 | list_for_each_entry(m, &ip6t_match, list) { |
| 528 | if (strcmp(m->name, name) == 0) { | ||
| 529 | if (m->revision == revision) { | ||
| 530 | if (try_module_get(m->me)) { | ||
| 531 | up(&ip6t_mutex); | ||
| 532 | return m; | ||
| 533 | } | ||
| 534 | } else | ||
| 535 | err = -EPROTOTYPE; /* Found something. */ | ||
| 536 | } | ||
| 524 | } | 537 | } |
| 525 | return ret; | 538 | up(&ip6t_mutex); |
| 539 | return ERR_PTR(err); | ||
| 526 | } | 540 | } |
| 527 | 541 | ||
| 528 | #ifndef CONFIG_KMOD | 542 | /* Find target, grabs ref. Returns ERR_PTR() on error. */ |
| 529 | #define find_inlist_lock(h,n,p,e,m) find_inlist_lock_noload((h),(n),(e),(m)) | 543 | static inline struct ip6t_target *find_target(const char *name, u8 revision) |
| 530 | #else | ||
| 531 | static void * | ||
| 532 | find_inlist_lock(struct list_head *head, | ||
| 533 | const char *name, | ||
| 534 | const char *prefix, | ||
| 535 | int *error, | ||
| 536 | struct semaphore *mutex) | ||
| 537 | { | 544 | { |
| 538 | void *ret; | 545 | struct ip6t_target *t; |
| 546 | int err = 0; | ||
| 539 | 547 | ||
| 540 | ret = find_inlist_lock_noload(head, name, error, mutex); | 548 | if (down_interruptible(&ip6t_mutex) != 0) |
| 541 | if (!ret) { | 549 | return ERR_PTR(-EINTR); |
| 542 | duprintf("find_inlist: loading `%s%s'.\n", prefix, name); | 550 | |
| 543 | request_module("%s%s", prefix, name); | 551 | list_for_each_entry(t, &ip6t_target, list) { |
| 544 | ret = find_inlist_lock_noload(head, name, error, mutex); | 552 | if (strcmp(t->name, name) == 0) { |
| 553 | if (t->revision == revision) { | ||
| 554 | if (try_module_get(t->me)) { | ||
| 555 | up(&ip6t_mutex); | ||
| 556 | return t; | ||
| 557 | } | ||
| 558 | } else | ||
| 559 | err = -EPROTOTYPE; /* Found something. */ | ||
| 560 | } | ||
| 545 | } | 561 | } |
| 562 | up(&ip6t_mutex); | ||
| 563 | return ERR_PTR(err); | ||
| 564 | } | ||
| 546 | 565 | ||
| 547 | return ret; | 566 | struct ip6t_target *ip6t_find_target(const char *name, u8 revision) |
| 567 | { | ||
| 568 | struct ip6t_target *target; | ||
| 569 | |||
| 570 | target = try_then_request_module(find_target(name, revision), | ||
| 571 | "ip6t_%s", name); | ||
| 572 | if (IS_ERR(target) || !target) | ||
| 573 | return NULL; | ||
| 574 | return target; | ||
| 548 | } | 575 | } |
| 549 | #endif | ||
| 550 | 576 | ||
| 551 | static inline struct ip6t_table * | 577 | static int match_revfn(const char *name, u8 revision, int *bestp) |
| 552 | ip6t_find_table_lock(const char *name, int *error, struct semaphore *mutex) | ||
| 553 | { | 578 | { |
| 554 | return find_inlist_lock(&ip6t_tables, name, "ip6table_", error, mutex); | 579 | struct ip6t_match *m; |
| 580 | int have_rev = 0; | ||
| 581 | |||
| 582 | list_for_each_entry(m, &ip6t_match, list) { | ||
| 583 | if (strcmp(m->name, name) == 0) { | ||
| 584 | if (m->revision > *bestp) | ||
| 585 | *bestp = m->revision; | ||
| 586 | if (m->revision == revision) | ||
| 587 | have_rev = 1; | ||
| 588 | } | ||
| 589 | } | ||
| 590 | return have_rev; | ||
| 555 | } | 591 | } |
| 556 | 592 | ||
| 557 | static inline struct ip6t_match * | 593 | static int target_revfn(const char *name, u8 revision, int *bestp) |
| 558 | find_match_lock(const char *name, int *error, struct semaphore *mutex) | ||
| 559 | { | 594 | { |
| 560 | return find_inlist_lock(&ip6t_match, name, "ip6t_", error, mutex); | 595 | struct ip6t_target *t; |
| 596 | int have_rev = 0; | ||
| 597 | |||
| 598 | list_for_each_entry(t, &ip6t_target, list) { | ||
| 599 | if (strcmp(t->name, name) == 0) { | ||
| 600 | if (t->revision > *bestp) | ||
| 601 | *bestp = t->revision; | ||
| 602 | if (t->revision == revision) | ||
| 603 | have_rev = 1; | ||
| 604 | } | ||
| 605 | } | ||
| 606 | return have_rev; | ||
| 561 | } | 607 | } |
| 562 | 608 | ||
| 563 | static struct ip6t_target * | 609 | /* Returns true or fals (if no such extension at all) */ |
| 564 | ip6t_find_target_lock(const char *name, int *error, struct semaphore *mutex) | 610 | static inline int find_revision(const char *name, u8 revision, |
| 611 | int (*revfn)(const char *, u8, int *), | ||
| 612 | int *err) | ||
| 565 | { | 613 | { |
| 566 | return find_inlist_lock(&ip6t_target, name, "ip6t_", error, mutex); | 614 | int have_rev, best = -1; |
| 615 | |||
| 616 | if (down_interruptible(&ip6t_mutex) != 0) { | ||
| 617 | *err = -EINTR; | ||
| 618 | return 1; | ||
| 619 | } | ||
| 620 | have_rev = revfn(name, revision, &best); | ||
| 621 | up(&ip6t_mutex); | ||
| 622 | |||
| 623 | /* Nothing at all? Return 0 to try loading module. */ | ||
| 624 | if (best == -1) { | ||
| 625 | *err = -ENOENT; | ||
| 626 | return 0; | ||
| 627 | } | ||
| 628 | |||
| 629 | *err = best; | ||
| 630 | if (!have_rev) | ||
| 631 | *err = -EPROTONOSUPPORT; | ||
| 632 | return 1; | ||
| 567 | } | 633 | } |
| 568 | 634 | ||
| 635 | |||
| 569 | /* All zeroes == unconditional rule. */ | 636 | /* All zeroes == unconditional rule. */ |
| 570 | static inline int | 637 | static inline int |
| 571 | unconditional(const struct ip6t_ip6 *ipv6) | 638 | unconditional(const struct ip6t_ip6 *ipv6) |
| @@ -725,20 +792,16 @@ check_match(struct ip6t_entry_match *m, | |||
| 725 | unsigned int hookmask, | 792 | unsigned int hookmask, |
| 726 | unsigned int *i) | 793 | unsigned int *i) |
| 727 | { | 794 | { |
| 728 | int ret; | ||
| 729 | struct ip6t_match *match; | 795 | struct ip6t_match *match; |
| 730 | 796 | ||
| 731 | match = find_match_lock(m->u.user.name, &ret, &ip6t_mutex); | 797 | match = try_then_request_module(find_match(m->u.user.name, |
| 732 | if (!match) { | 798 | m->u.user.revision), |
| 733 | // duprintf("check_match: `%s' not found\n", m->u.name); | 799 | "ip6t_%s", m->u.user.name); |
| 734 | return ret; | 800 | if (IS_ERR(match) || !match) { |
| 735 | } | 801 | duprintf("check_match: `%s' not found\n", m->u.user.name); |
| 736 | if (!try_module_get(match->me)) { | 802 | return match ? PTR_ERR(match) : -ENOENT; |
| 737 | up(&ip6t_mutex); | ||
| 738 | return -ENOENT; | ||
| 739 | } | 803 | } |
| 740 | m->u.kernel.match = match; | 804 | m->u.kernel.match = match; |
| 741 | up(&ip6t_mutex); | ||
| 742 | 805 | ||
| 743 | if (m->u.kernel.match->checkentry | 806 | if (m->u.kernel.match->checkentry |
| 744 | && !m->u.kernel.match->checkentry(name, ipv6, m->data, | 807 | && !m->u.kernel.match->checkentry(name, ipv6, m->data, |
| @@ -776,22 +839,16 @@ check_entry(struct ip6t_entry *e, const char *name, unsigned int size, | |||
| 776 | goto cleanup_matches; | 839 | goto cleanup_matches; |
| 777 | 840 | ||
| 778 | t = ip6t_get_target(e); | 841 | t = ip6t_get_target(e); |
| 779 | target = ip6t_find_target_lock(t->u.user.name, &ret, &ip6t_mutex); | 842 | target = try_then_request_module(find_target(t->u.user.name, |
| 780 | if (!target) { | 843 | t->u.user.revision), |
| 844 | "ip6t_%s", t->u.user.name); | ||
| 845 | if (IS_ERR(target) || !target) { | ||
| 781 | duprintf("check_entry: `%s' not found\n", t->u.user.name); | 846 | duprintf("check_entry: `%s' not found\n", t->u.user.name); |
| 782 | goto cleanup_matches; | 847 | ret = target ? PTR_ERR(target) : -ENOENT; |
| 783 | } | ||
| 784 | if (!try_module_get(target->me)) { | ||
| 785 | up(&ip6t_mutex); | ||
| 786 | ret = -ENOENT; | ||
| 787 | goto cleanup_matches; | 848 | goto cleanup_matches; |
| 788 | } | 849 | } |
| 789 | t->u.kernel.target = target; | 850 | t->u.kernel.target = target; |
| 790 | up(&ip6t_mutex); | 851 | |
| 791 | if (!t->u.kernel.target) { | ||
| 792 | ret = -EBUSY; | ||
| 793 | goto cleanup_matches; | ||
| 794 | } | ||
| 795 | if (t->u.kernel.target == &ip6t_standard_target) { | 852 | if (t->u.kernel.target == &ip6t_standard_target) { |
| 796 | if (!standard_check(t, size)) { | 853 | if (!standard_check(t, size)) { |
| 797 | ret = -EINVAL; | 854 | ret = -EINVAL; |
| @@ -1118,8 +1175,8 @@ get_entries(const struct ip6t_get_entries *entries, | |||
| 1118 | int ret; | 1175 | int ret; |
| 1119 | struct ip6t_table *t; | 1176 | struct ip6t_table *t; |
| 1120 | 1177 | ||
| 1121 | t = ip6t_find_table_lock(entries->name, &ret, &ip6t_mutex); | 1178 | t = find_table_lock(entries->name); |
| 1122 | if (t) { | 1179 | if (t && !IS_ERR(t)) { |
| 1123 | duprintf("t->private->number = %u\n", | 1180 | duprintf("t->private->number = %u\n", |
| 1124 | t->private->number); | 1181 | t->private->number); |
| 1125 | if (entries->size == t->private->size) | 1182 | if (entries->size == t->private->size) |
| @@ -1131,10 +1188,10 @@ get_entries(const struct ip6t_get_entries *entries, | |||
| 1131 | entries->size); | 1188 | entries->size); |
| 1132 | ret = -EINVAL; | 1189 | ret = -EINVAL; |
| 1133 | } | 1190 | } |
| 1191 | module_put(t->me); | ||
| 1134 | up(&ip6t_mutex); | 1192 | up(&ip6t_mutex); |
| 1135 | } else | 1193 | } else |
| 1136 | duprintf("get_entries: Can't find %s!\n", | 1194 | ret = t ? PTR_ERR(t) : -ENOENT; |
| 1137 | entries->name); | ||
| 1138 | 1195 | ||
| 1139 | return ret; | 1196 | return ret; |
| 1140 | } | 1197 | } |
| @@ -1182,22 +1239,19 @@ do_replace(void __user *user, unsigned int len) | |||
| 1182 | 1239 | ||
| 1183 | duprintf("ip_tables: Translated table\n"); | 1240 | duprintf("ip_tables: Translated table\n"); |
| 1184 | 1241 | ||
| 1185 | t = ip6t_find_table_lock(tmp.name, &ret, &ip6t_mutex); | 1242 | t = try_then_request_module(find_table_lock(tmp.name), |
| 1186 | if (!t) | 1243 | "ip6table_%s", tmp.name); |
| 1244 | if (!t || IS_ERR(t)) { | ||
| 1245 | ret = t ? PTR_ERR(t) : -ENOENT; | ||
| 1187 | goto free_newinfo_counters_untrans; | 1246 | goto free_newinfo_counters_untrans; |
| 1247 | } | ||
| 1188 | 1248 | ||
| 1189 | /* You lied! */ | 1249 | /* You lied! */ |
| 1190 | if (tmp.valid_hooks != t->valid_hooks) { | 1250 | if (tmp.valid_hooks != t->valid_hooks) { |
| 1191 | duprintf("Valid hook crap: %08X vs %08X\n", | 1251 | duprintf("Valid hook crap: %08X vs %08X\n", |
| 1192 | tmp.valid_hooks, t->valid_hooks); | 1252 | tmp.valid_hooks, t->valid_hooks); |
| 1193 | ret = -EINVAL; | 1253 | ret = -EINVAL; |
| 1194 | goto free_newinfo_counters_untrans_unlock; | 1254 | goto put_module; |
| 1195 | } | ||
| 1196 | |||
| 1197 | /* Get a reference in advance, we're not allowed fail later */ | ||
| 1198 | if (!try_module_get(t->me)) { | ||
| 1199 | ret = -EBUSY; | ||
| 1200 | goto free_newinfo_counters_untrans_unlock; | ||
| 1201 | } | 1255 | } |
| 1202 | 1256 | ||
| 1203 | oldinfo = replace_table(t, tmp.num_counters, newinfo, &ret); | 1257 | oldinfo = replace_table(t, tmp.num_counters, newinfo, &ret); |
| @@ -1219,7 +1273,6 @@ do_replace(void __user *user, unsigned int len) | |||
| 1219 | /* Decrease module usage counts and free resource */ | 1273 | /* Decrease module usage counts and free resource */ |
| 1220 | IP6T_ENTRY_ITERATE(oldinfo->entries, oldinfo->size, cleanup_entry,NULL); | 1274 | IP6T_ENTRY_ITERATE(oldinfo->entries, oldinfo->size, cleanup_entry,NULL); |
| 1221 | vfree(oldinfo); | 1275 | vfree(oldinfo); |
| 1222 | /* Silent error: too late now. */ | ||
| 1223 | if (copy_to_user(tmp.counters, counters, | 1276 | if (copy_to_user(tmp.counters, counters, |
| 1224 | sizeof(struct ip6t_counters) * tmp.num_counters) != 0) | 1277 | sizeof(struct ip6t_counters) * tmp.num_counters) != 0) |
| 1225 | ret = -EFAULT; | 1278 | ret = -EFAULT; |
| @@ -1229,7 +1282,6 @@ do_replace(void __user *user, unsigned int len) | |||
| 1229 | 1282 | ||
| 1230 | put_module: | 1283 | put_module: |
| 1231 | module_put(t->me); | 1284 | module_put(t->me); |
| 1232 | free_newinfo_counters_untrans_unlock: | ||
| 1233 | up(&ip6t_mutex); | 1285 | up(&ip6t_mutex); |
| 1234 | free_newinfo_counters_untrans: | 1286 | free_newinfo_counters_untrans: |
| 1235 | IP6T_ENTRY_ITERATE(newinfo->entries, newinfo->size, cleanup_entry,NULL); | 1287 | IP6T_ENTRY_ITERATE(newinfo->entries, newinfo->size, cleanup_entry,NULL); |
| @@ -1268,7 +1320,7 @@ do_add_counters(void __user *user, unsigned int len) | |||
| 1268 | unsigned int i; | 1320 | unsigned int i; |
| 1269 | struct ip6t_counters_info tmp, *paddc; | 1321 | struct ip6t_counters_info tmp, *paddc; |
| 1270 | struct ip6t_table *t; | 1322 | struct ip6t_table *t; |
| 1271 | int ret; | 1323 | int ret = 0; |
| 1272 | 1324 | ||
| 1273 | if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) | 1325 | if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) |
| 1274 | return -EFAULT; | 1326 | return -EFAULT; |
| @@ -1285,9 +1337,11 @@ do_add_counters(void __user *user, unsigned int len) | |||
| 1285 | goto free; | 1337 | goto free; |
| 1286 | } | 1338 | } |
| 1287 | 1339 | ||
| 1288 | t = ip6t_find_table_lock(tmp.name, &ret, &ip6t_mutex); | 1340 | t = find_table_lock(tmp.name); |
| 1289 | if (!t) | 1341 | if (!t || IS_ERR(t)) { |
| 1342 | ret = t ? PTR_ERR(t) : -ENOENT; | ||
| 1290 | goto free; | 1343 | goto free; |
| 1344 | } | ||
| 1291 | 1345 | ||
| 1292 | write_lock_bh(&t->lock); | 1346 | write_lock_bh(&t->lock); |
| 1293 | if (t->private->number != paddc->num_counters) { | 1347 | if (t->private->number != paddc->num_counters) { |
| @@ -1304,6 +1358,7 @@ do_add_counters(void __user *user, unsigned int len) | |||
| 1304 | unlock_up_free: | 1358 | unlock_up_free: |
| 1305 | write_unlock_bh(&t->lock); | 1359 | write_unlock_bh(&t->lock); |
| 1306 | up(&ip6t_mutex); | 1360 | up(&ip6t_mutex); |
| 1361 | module_put(t->me); | ||
| 1307 | free: | 1362 | free: |
| 1308 | vfree(paddc); | 1363 | vfree(paddc); |
| 1309 | 1364 | ||
| @@ -1360,8 +1415,10 @@ do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) | |||
| 1360 | break; | 1415 | break; |
| 1361 | } | 1416 | } |
| 1362 | name[IP6T_TABLE_MAXNAMELEN-1] = '\0'; | 1417 | name[IP6T_TABLE_MAXNAMELEN-1] = '\0'; |
| 1363 | t = ip6t_find_table_lock(name, &ret, &ip6t_mutex); | 1418 | |
| 1364 | if (t) { | 1419 | t = try_then_request_module(find_table_lock(name), |
| 1420 | "ip6table_%s", name); | ||
| 1421 | if (t && !IS_ERR(t)) { | ||
| 1365 | struct ip6t_getinfo info; | 1422 | struct ip6t_getinfo info; |
| 1366 | 1423 | ||
| 1367 | info.valid_hooks = t->valid_hooks; | 1424 | info.valid_hooks = t->valid_hooks; |
| @@ -1377,9 +1434,10 @@ do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) | |||
| 1377 | ret = -EFAULT; | 1434 | ret = -EFAULT; |
| 1378 | else | 1435 | else |
| 1379 | ret = 0; | 1436 | ret = 0; |
| 1380 | |||
| 1381 | up(&ip6t_mutex); | 1437 | up(&ip6t_mutex); |
| 1382 | } | 1438 | module_put(t->me); |
| 1439 | } else | ||
| 1440 | ret = t ? PTR_ERR(t) : -ENOENT; | ||
| 1383 | } | 1441 | } |
| 1384 | break; | 1442 | break; |
| 1385 | 1443 | ||
| @@ -1400,6 +1458,31 @@ do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) | |||
| 1400 | break; | 1458 | break; |
| 1401 | } | 1459 | } |
| 1402 | 1460 | ||
| 1461 | case IP6T_SO_GET_REVISION_MATCH: | ||
| 1462 | case IP6T_SO_GET_REVISION_TARGET: { | ||
| 1463 | struct ip6t_get_revision rev; | ||
| 1464 | int (*revfn)(const char *, u8, int *); | ||
| 1465 | |||
| 1466 | if (*len != sizeof(rev)) { | ||
| 1467 | ret = -EINVAL; | ||
| 1468 | break; | ||
| 1469 | } | ||
| 1470 | if (copy_from_user(&rev, user, sizeof(rev)) != 0) { | ||
| 1471 | ret = -EFAULT; | ||
| 1472 | break; | ||
| 1473 | } | ||
| 1474 | |||
| 1475 | if (cmd == IP6T_SO_GET_REVISION_TARGET) | ||
| 1476 | revfn = target_revfn; | ||
| 1477 | else | ||
| 1478 | revfn = match_revfn; | ||
| 1479 | |||
| 1480 | try_then_request_module(find_revision(rev.name, rev.revision, | ||
| 1481 | revfn, &ret), | ||
| 1482 | "ip6t_%s", rev.name); | ||
| 1483 | break; | ||
| 1484 | } | ||
| 1485 | |||
| 1403 | default: | 1486 | default: |
| 1404 | duprintf("do_ip6t_get_ctl: unknown request %i\n", cmd); | 1487 | duprintf("do_ip6t_get_ctl: unknown request %i\n", cmd); |
| 1405 | ret = -EINVAL; | 1488 | ret = -EINVAL; |
| @@ -1417,12 +1500,7 @@ ip6t_register_target(struct ip6t_target *target) | |||
| 1417 | ret = down_interruptible(&ip6t_mutex); | 1500 | ret = down_interruptible(&ip6t_mutex); |
| 1418 | if (ret != 0) | 1501 | if (ret != 0) |
| 1419 | return ret; | 1502 | return ret; |
| 1420 | 1503 | list_add(&target->list, &ip6t_target); | |
| 1421 | if (!list_named_insert(&ip6t_target, target)) { | ||
| 1422 | duprintf("ip6t_register_target: `%s' already in list!\n", | ||
| 1423 | target->name); | ||
| 1424 | ret = -EINVAL; | ||
| 1425 | } | ||
| 1426 | up(&ip6t_mutex); | 1504 | up(&ip6t_mutex); |
| 1427 | return ret; | 1505 | return ret; |
| 1428 | } | 1506 | } |
| @@ -1444,11 +1522,7 @@ ip6t_register_match(struct ip6t_match *match) | |||
| 1444 | if (ret != 0) | 1522 | if (ret != 0) |
| 1445 | return ret; | 1523 | return ret; |
| 1446 | 1524 | ||
| 1447 | if (!list_named_insert(&ip6t_match, match)) { | 1525 | list_add(&match->list, &ip6t_match); |
| 1448 | duprintf("ip6t_register_match: `%s' already in list!\n", | ||
| 1449 | match->name); | ||
| 1450 | ret = -EINVAL; | ||
| 1451 | } | ||
| 1452 | up(&ip6t_mutex); | 1526 | up(&ip6t_mutex); |
| 1453 | 1527 | ||
| 1454 | return ret; | 1528 | return ret; |
diff --git a/net/ipv6/netfilter/ip6t_MARK.c b/net/ipv6/netfilter/ip6t_MARK.c index 81924fcc5857..0c7584f92172 100644 --- a/net/ipv6/netfilter/ip6t_MARK.c +++ b/net/ipv6/netfilter/ip6t_MARK.c | |||
| @@ -56,8 +56,12 @@ checkentry(const char *tablename, | |||
| 56 | return 1; | 56 | return 1; |
| 57 | } | 57 | } |
| 58 | 58 | ||
| 59 | static struct ip6t_target ip6t_mark_reg | 59 | static struct ip6t_target ip6t_mark_reg = { |
| 60 | = { { NULL, NULL }, "MARK", target, checkentry, NULL, THIS_MODULE }; | 60 | .name = "MARK", |
| 61 | .target = target, | ||
| 62 | .checkentry = checkentry, | ||
| 63 | .me = THIS_MODULE | ||
| 64 | }; | ||
| 61 | 65 | ||
| 62 | static int __init init(void) | 66 | static int __init init(void) |
| 63 | { | 67 | { |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 5d5bbb49ec78..227e99ed510c 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
| @@ -483,7 +483,7 @@ restart: | |||
| 483 | goto out; | 483 | goto out; |
| 484 | } | 484 | } |
| 485 | 485 | ||
| 486 | rt = rt6_device_match(rt, skb->dev->ifindex, 0); | 486 | rt = rt6_device_match(rt, skb->dev->ifindex, strict); |
| 487 | BACKTRACK(); | 487 | BACKTRACK(); |
| 488 | 488 | ||
| 489 | if (!rt->rt6i_nexthop && !(rt->rt6i_flags & RTF_NONEXTHOP)) { | 489 | if (!rt->rt6i_nexthop && !(rt->rt6i_flags & RTF_NONEXTHOP)) { |
diff --git a/net/rose/rose_timer.c b/net/rose/rose_timer.c index 50ae0371dab8..b6c8f38cc26c 100644 --- a/net/rose/rose_timer.c +++ b/net/rose/rose_timer.c | |||
| @@ -138,6 +138,7 @@ static void rose_heartbeat_expiry(unsigned long param) | |||
| 138 | is accepted() it isn't 'dead' so doesn't get removed. */ | 138 | is accepted() it isn't 'dead' so doesn't get removed. */ |
| 139 | if (sock_flag(sk, SOCK_DESTROY) || | 139 | if (sock_flag(sk, SOCK_DESTROY) || |
| 140 | (sk->sk_state == TCP_LISTEN && sock_flag(sk, SOCK_DEAD))) { | 140 | (sk->sk_state == TCP_LISTEN && sock_flag(sk, SOCK_DEAD))) { |
| 141 | bh_unlock_sock(sk); | ||
| 141 | rose_destroy_socket(sk); | 142 | rose_destroy_socket(sk); |
| 142 | return; | 143 | return; |
| 143 | } | 144 | } |
diff --git a/net/sched/Kconfig b/net/sched/Kconfig index 81510da31792..7f34e7fd767c 100644 --- a/net/sched/Kconfig +++ b/net/sched/Kconfig | |||
| @@ -2,13 +2,15 @@ | |||
| 2 | # Traffic control configuration. | 2 | # Traffic control configuration. |
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | menuconfig NET_SCHED | 5 | menu "QoS and/or fair queueing" |
| 6 | |||
| 7 | config NET_SCHED | ||
| 6 | bool "QoS and/or fair queueing" | 8 | bool "QoS and/or fair queueing" |
| 7 | ---help--- | 9 | ---help--- |
| 8 | When the kernel has several packets to send out over a network | 10 | When the kernel has several packets to send out over a network |
| 9 | device, it has to decide which ones to send first, which ones to | 11 | device, it has to decide which ones to send first, which ones to |
| 10 | delay, and which ones to drop. This is the job of the packet | 12 | delay, and which ones to drop. This is the job of the queueing |
| 11 | scheduler, and several different algorithms for how to do this | 13 | disciplines, several different algorithms for how to do this |
| 12 | "fairly" have been proposed. | 14 | "fairly" have been proposed. |
| 13 | 15 | ||
| 14 | If you say N here, you will get the standard packet scheduler, which | 16 | If you say N here, you will get the standard packet scheduler, which |
| @@ -23,13 +25,13 @@ menuconfig NET_SCHED | |||
| 23 | To administer these schedulers, you'll need the user-level utilities | 25 | To administer these schedulers, you'll need the user-level utilities |
| 24 | from the package iproute2+tc at <ftp://ftp.tux.org/pub/net/ip-routing/>. | 26 | from the package iproute2+tc at <ftp://ftp.tux.org/pub/net/ip-routing/>. |
| 25 | That package also contains some documentation; for more, check out | 27 | That package also contains some documentation; for more, check out |
| 26 | <http://snafu.freedom.org/linux2.2/iproute-notes.html>. | 28 | <http://linux-net.osdl.org/index.php/Iproute2>. |
| 27 | 29 | ||
| 28 | This Quality of Service (QoS) support will enable you to use | 30 | This Quality of Service (QoS) support will enable you to use |
| 29 | Differentiated Services (diffserv) and Resource Reservation Protocol | 31 | Differentiated Services (diffserv) and Resource Reservation Protocol |
| 30 | (RSVP) on your Linux router if you also say Y to "QoS support", | 32 | (RSVP) on your Linux router if you also say Y to the corresponding |
| 31 | "Packet classifier API" and to some classifiers below. Documentation | 33 | classifiers below. Documentation and software is at |
| 32 | and software is at <http://diffserv.sourceforge.net/>. | 34 | <http://diffserv.sourceforge.net/>. |
| 33 | 35 | ||
| 34 | If you say Y here and to "/proc file system" below, you will be able | 36 | If you say Y here and to "/proc file system" below, you will be able |
| 35 | to read status information about packet schedulers from the file | 37 | to read status information about packet schedulers from the file |
| @@ -42,7 +44,7 @@ choice | |||
| 42 | prompt "Packet scheduler clock source" | 44 | prompt "Packet scheduler clock source" |
| 43 | depends on NET_SCHED | 45 | depends on NET_SCHED |
| 44 | default NET_SCH_CLK_JIFFIES | 46 | default NET_SCH_CLK_JIFFIES |
| 45 | help | 47 | ---help--- |
| 46 | Packet schedulers need a monotonic clock that increments at a static | 48 | Packet schedulers need a monotonic clock that increments at a static |
| 47 | rate. The kernel provides several suitable interfaces, each with | 49 | rate. The kernel provides several suitable interfaces, each with |
| 48 | different properties: | 50 | different properties: |
| @@ -56,7 +58,7 @@ choice | |||
| 56 | 58 | ||
| 57 | config NET_SCH_CLK_JIFFIES | 59 | config NET_SCH_CLK_JIFFIES |
| 58 | bool "Timer interrupt" | 60 | bool "Timer interrupt" |
| 59 | help | 61 | ---help--- |
| 60 | Say Y here if you want to use the timer interrupt (jiffies) as clock | 62 | Say Y here if you want to use the timer interrupt (jiffies) as clock |
| 61 | source. This clock source is fast, synchronized on all processors and | 63 | source. This clock source is fast, synchronized on all processors and |
| 62 | handles cpu clock frequency changes, but its resolution is too low | 64 | handles cpu clock frequency changes, but its resolution is too low |
| @@ -64,7 +66,7 @@ config NET_SCH_CLK_JIFFIES | |||
| 64 | 66 | ||
| 65 | config NET_SCH_CLK_GETTIMEOFDAY | 67 | config NET_SCH_CLK_GETTIMEOFDAY |
| 66 | bool "gettimeofday" | 68 | bool "gettimeofday" |
| 67 | help | 69 | ---help--- |
| 68 | Say Y here if you want to use gettimeofday as clock source. This clock | 70 | Say Y here if you want to use gettimeofday as clock source. This clock |
| 69 | source has high resolution, is synchronized on all processors and | 71 | source has high resolution, is synchronized on all processors and |
| 70 | handles cpu clock frequency changes, but it is slow. | 72 | handles cpu clock frequency changes, but it is slow. |
| @@ -77,7 +79,7 @@ config NET_SCH_CLK_GETTIMEOFDAY | |||
| 77 | config NET_SCH_CLK_CPU | 79 | config NET_SCH_CLK_CPU |
| 78 | bool "CPU cycle counter" | 80 | bool "CPU cycle counter" |
| 79 | depends on ((X86_TSC || X86_64) && !SMP) || ALPHA || SPARC64 || PPC64 || IA64 | 81 | depends on ((X86_TSC || X86_64) && !SMP) || ALPHA || SPARC64 || PPC64 || IA64 |
| 80 | help | 82 | ---help--- |
| 81 | Say Y here if you want to use the CPU's cycle counter as clock source. | 83 | Say Y here if you want to use the CPU's cycle counter as clock source. |
| 82 | This is a cheap and high resolution clock source, but on some | 84 | This is a cheap and high resolution clock source, but on some |
| 83 | architectures it is not synchronized on all processors and doesn't | 85 | architectures it is not synchronized on all processors and doesn't |
| @@ -95,134 +97,129 @@ config NET_SCH_CLK_CPU | |||
| 95 | 97 | ||
| 96 | endchoice | 98 | endchoice |
| 97 | 99 | ||
| 100 | comment "Queueing/Scheduling" | ||
| 101 | depends on NET_SCHED | ||
| 102 | |||
| 98 | config NET_SCH_CBQ | 103 | config NET_SCH_CBQ |
| 99 | tristate "CBQ packet scheduler" | 104 | tristate "Class Based Queueing (CBQ)" |
| 100 | depends on NET_SCHED | 105 | depends on NET_SCHED |
| 101 | ---help--- | 106 | ---help--- |
| 102 | Say Y here if you want to use the Class-Based Queueing (CBQ) packet | 107 | Say Y here if you want to use the Class-Based Queueing (CBQ) packet |
| 103 | scheduling algorithm for some of your network devices. This | 108 | scheduling algorithm. This algorithm classifies the waiting packets |
| 104 | algorithm classifies the waiting packets into a tree-like hierarchy | 109 | into a tree-like hierarchy of classes; the leaves of this tree are |
| 105 | of classes; the leaves of this tree are in turn scheduled by | 110 | in turn scheduled by separate algorithms. |
| 106 | separate algorithms (called "disciplines" in this context). | ||
| 107 | 111 | ||
| 108 | See the top of <file:net/sched/sch_cbq.c> for references about the | 112 | See the top of <file:net/sched/sch_cbq.c> for more details. |
| 109 | CBQ algorithm. | ||
| 110 | 113 | ||
| 111 | CBQ is a commonly used scheduler, so if you're unsure, you should | 114 | CBQ is a commonly used scheduler, so if you're unsure, you should |
| 112 | say Y here. Then say Y to all the queueing algorithms below that you | 115 | say Y here. Then say Y to all the queueing algorithms below that you |
| 113 | want to use as CBQ disciplines. Then say Y to "Packet classifier | 116 | want to use as leaf disciplines. |
| 114 | API" and say Y to all the classifiers you want to use; a classifier | ||
| 115 | is a routine that allows you to sort your outgoing traffic into | ||
| 116 | classes based on a certain criterion. | ||
| 117 | 117 | ||
| 118 | To compile this code as a module, choose M here: the | 118 | To compile this code as a module, choose M here: the |
| 119 | module will be called sch_cbq. | 119 | module will be called sch_cbq. |
| 120 | 120 | ||
| 121 | config NET_SCH_HTB | 121 | config NET_SCH_HTB |
| 122 | tristate "HTB packet scheduler" | 122 | tristate "Hierarchical Token Bucket (HTB)" |
| 123 | depends on NET_SCHED | 123 | depends on NET_SCHED |
| 124 | ---help--- | 124 | ---help--- |
| 125 | Say Y here if you want to use the Hierarchical Token Buckets (HTB) | 125 | Say Y here if you want to use the Hierarchical Token Buckets (HTB) |
| 126 | packet scheduling algorithm for some of your network devices. See | 126 | packet scheduling algorithm. See |
| 127 | <http://luxik.cdi.cz/~devik/qos/htb/> for complete manual and | 127 | <http://luxik.cdi.cz/~devik/qos/htb/> for complete manual and |
| 128 | in-depth articles. | 128 | in-depth articles. |
| 129 | 129 | ||
| 130 | HTB is very similar to the CBQ regarding its goals however is has | 130 | HTB is very similar to CBQ regarding its goals however is has |
| 131 | different properties and different algorithm. | 131 | different properties and different algorithm. |
| 132 | 132 | ||
| 133 | To compile this code as a module, choose M here: the | 133 | To compile this code as a module, choose M here: the |
| 134 | module will be called sch_htb. | 134 | module will be called sch_htb. |
| 135 | 135 | ||
| 136 | config NET_SCH_HFSC | 136 | config NET_SCH_HFSC |
| 137 | tristate "HFSC packet scheduler" | 137 | tristate "Hierarchical Fair Service Curve (HFSC)" |
| 138 | depends on NET_SCHED | 138 | depends on NET_SCHED |
| 139 | ---help--- | 139 | ---help--- |
| 140 | Say Y here if you want to use the Hierarchical Fair Service Curve | 140 | Say Y here if you want to use the Hierarchical Fair Service Curve |
| 141 | (HFSC) packet scheduling algorithm for some of your network devices. | 141 | (HFSC) packet scheduling algorithm. |
| 142 | 142 | ||
| 143 | To compile this code as a module, choose M here: the | 143 | To compile this code as a module, choose M here: the |
| 144 | module will be called sch_hfsc. | 144 | module will be called sch_hfsc. |
| 145 | 145 | ||
| 146 | #tristate ' H-PFQ packet scheduler' CONFIG_NET_SCH_HPFQ | ||
| 147 | config NET_SCH_ATM | 146 | config NET_SCH_ATM |
| 148 | tristate "ATM pseudo-scheduler" | 147 | tristate "ATM Virtual Circuits (ATM)" |
| 149 | depends on NET_SCHED && ATM | 148 | depends on NET_SCHED && ATM |
| 150 | ---help--- | 149 | ---help--- |
| 151 | Say Y here if you want to use the ATM pseudo-scheduler. This | 150 | Say Y here if you want to use the ATM pseudo-scheduler. This |
| 152 | provides a framework for invoking classifiers (aka "filters"), which | 151 | provides a framework for invoking classifiers, which in turn |
| 153 | in turn select classes of this queuing discipline. Each class maps | 152 | select classes of this queuing discipline. Each class maps |
| 154 | the flow(s) it is handling to a given virtual circuit (see the top of | 153 | the flow(s) it is handling to a given virtual circuit. |
| 155 | <file:net/sched/sch_atm.c>). | 154 | |
| 155 | See the top of <file:net/sched/sch_atm.c>) for more details. | ||
| 156 | 156 | ||
| 157 | To compile this code as a module, choose M here: the | 157 | To compile this code as a module, choose M here: the |
| 158 | module will be called sch_atm. | 158 | module will be called sch_atm. |
| 159 | 159 | ||
| 160 | config NET_SCH_PRIO | 160 | config NET_SCH_PRIO |
| 161 | tristate "The simplest PRIO pseudoscheduler" | 161 | tristate "Multi Band Priority Queueing (PRIO)" |
| 162 | depends on NET_SCHED | 162 | depends on NET_SCHED |
| 163 | help | 163 | ---help--- |
| 164 | Say Y here if you want to use an n-band priority queue packet | 164 | Say Y here if you want to use an n-band priority queue packet |
| 165 | "scheduler" for some of your network devices or as a leaf discipline | 165 | scheduler. |
| 166 | for the CBQ scheduling algorithm. If unsure, say Y. | ||
| 167 | 166 | ||
| 168 | To compile this code as a module, choose M here: the | 167 | To compile this code as a module, choose M here: the |
| 169 | module will be called sch_prio. | 168 | module will be called sch_prio. |
| 170 | 169 | ||
| 171 | config NET_SCH_RED | 170 | config NET_SCH_RED |
| 172 | tristate "RED queue" | 171 | tristate "Random Early Detection (RED)" |
| 173 | depends on NET_SCHED | 172 | depends on NET_SCHED |
| 174 | help | 173 | ---help--- |
| 175 | Say Y here if you want to use the Random Early Detection (RED) | 174 | Say Y here if you want to use the Random Early Detection (RED) |
| 176 | packet scheduling algorithm for some of your network devices (see | 175 | packet scheduling algorithm. |
| 177 | the top of <file:net/sched/sch_red.c> for details and references | 176 | |
| 178 | about the algorithm). | 177 | See the top of <file:net/sched/sch_red.c> for more details. |
| 179 | 178 | ||
| 180 | To compile this code as a module, choose M here: the | 179 | To compile this code as a module, choose M here: the |
| 181 | module will be called sch_red. | 180 | module will be called sch_red. |
| 182 | 181 | ||
| 183 | config NET_SCH_SFQ | 182 | config NET_SCH_SFQ |
| 184 | tristate "SFQ queue" | 183 | tristate "Stochastic Fairness Queueing (SFQ)" |
| 185 | depends on NET_SCHED | 184 | depends on NET_SCHED |
| 186 | ---help--- | 185 | ---help--- |
| 187 | Say Y here if you want to use the Stochastic Fairness Queueing (SFQ) | 186 | Say Y here if you want to use the Stochastic Fairness Queueing (SFQ) |
| 188 | packet scheduling algorithm for some of your network devices or as a | 187 | packet scheduling algorithm . |
| 189 | leaf discipline for the CBQ scheduling algorithm (see the top of | 188 | |
| 190 | <file:net/sched/sch_sfq.c> for details and references about the SFQ | 189 | See the top of <file:net/sched/sch_sfq.c> for more details. |
| 191 | algorithm). | ||
| 192 | 190 | ||
| 193 | To compile this code as a module, choose M here: the | 191 | To compile this code as a module, choose M here: the |
| 194 | module will be called sch_sfq. | 192 | module will be called sch_sfq. |
| 195 | 193 | ||
| 196 | config NET_SCH_TEQL | 194 | config NET_SCH_TEQL |
| 197 | tristate "TEQL queue" | 195 | tristate "True Link Equalizer (TEQL)" |
| 198 | depends on NET_SCHED | 196 | depends on NET_SCHED |
| 199 | ---help--- | 197 | ---help--- |
| 200 | Say Y here if you want to use the True Link Equalizer (TLE) packet | 198 | Say Y here if you want to use the True Link Equalizer (TLE) packet |
| 201 | scheduling algorithm for some of your network devices or as a leaf | 199 | scheduling algorithm. This queueing discipline allows the combination |
| 202 | discipline for the CBQ scheduling algorithm. This queueing | 200 | of several physical devices into one virtual device. |
| 203 | discipline allows the combination of several physical devices into | 201 | |
| 204 | one virtual device. (see the top of <file:net/sched/sch_teql.c> for | 202 | See the top of <file:net/sched/sch_teql.c> for more details. |
| 205 | details). | ||
| 206 | 203 | ||
| 207 | To compile this code as a module, choose M here: the | 204 | To compile this code as a module, choose M here: the |
| 208 | module will be called sch_teql. | 205 | module will be called sch_teql. |
| 209 | 206 | ||
| 210 | config NET_SCH_TBF | 207 | config NET_SCH_TBF |
| 211 | tristate "TBF queue" | 208 | tristate "Token Bucket Filter (TBF)" |
| 212 | depends on NET_SCHED | 209 | depends on NET_SCHED |
| 213 | help | 210 | ---help--- |
| 214 | Say Y here if you want to use the Simple Token Bucket Filter (TBF) | 211 | Say Y here if you want to use the Token Bucket Filter (TBF) packet |
| 215 | packet scheduling algorithm for some of your network devices or as a | 212 | scheduling algorithm. |
| 216 | leaf discipline for the CBQ scheduling algorithm (see the top of | 213 | |
| 217 | <file:net/sched/sch_tbf.c> for a description of the TBF algorithm). | 214 | See the top of <file:net/sched/sch_tbf.c> for more details. |
| 218 | 215 | ||
| 219 | To compile this code as a module, choose M here: the | 216 | To compile this code as a module, choose M here: the |
| 220 | module will be called sch_tbf. | 217 | module will be called sch_tbf. |
| 221 | 218 | ||
| 222 | config NET_SCH_GRED | 219 | config NET_SCH_GRED |
| 223 | tristate "GRED queue" | 220 | tristate "Generic Random Early Detection (GRED)" |
| 224 | depends on NET_SCHED | 221 | depends on NET_SCHED |
| 225 | help | 222 | ---help--- |
| 226 | Say Y here if you want to use the Generic Random Early Detection | 223 | Say Y here if you want to use the Generic Random Early Detection |
| 227 | (GRED) packet scheduling algorithm for some of your network devices | 224 | (GRED) packet scheduling algorithm for some of your network devices |
| 228 | (see the top of <file:net/sched/sch_red.c> for details and | 225 | (see the top of <file:net/sched/sch_red.c> for details and |
| @@ -232,9 +229,9 @@ config NET_SCH_GRED | |||
| 232 | module will be called sch_gred. | 229 | module will be called sch_gred. |
| 233 | 230 | ||
| 234 | config NET_SCH_DSMARK | 231 | config NET_SCH_DSMARK |
| 235 | tristate "Diffserv field marker" | 232 | tristate "Differentiated Services marker (DSMARK)" |
| 236 | depends on NET_SCHED | 233 | depends on NET_SCHED |
| 237 | help | 234 | ---help--- |
| 238 | Say Y if you want to schedule packets according to the | 235 | Say Y if you want to schedule packets according to the |
| 239 | Differentiated Services architecture proposed in RFC 2475. | 236 | Differentiated Services architecture proposed in RFC 2475. |
| 240 | Technical information on this method, with pointers to associated | 237 | Technical information on this method, with pointers to associated |
| @@ -244,9 +241,9 @@ config NET_SCH_DSMARK | |||
| 244 | module will be called sch_dsmark. | 241 | module will be called sch_dsmark. |
| 245 | 242 | ||
| 246 | config NET_SCH_NETEM | 243 | config NET_SCH_NETEM |
| 247 | tristate "Network emulator" | 244 | tristate "Network emulator (NETEM)" |
| 248 | depends on NET_SCHED | 245 | depends on NET_SCHED |
| 249 | help | 246 | ---help--- |
| 250 | Say Y if you want to emulate network delay, loss, and packet | 247 | Say Y if you want to emulate network delay, loss, and packet |
| 251 | re-ordering. This is often useful to simulate networks when | 248 | re-ordering. This is often useful to simulate networks when |
| 252 | testing applications or protocols. | 249 | testing applications or protocols. |
| @@ -259,58 +256,23 @@ config NET_SCH_NETEM | |||
| 259 | config NET_SCH_INGRESS | 256 | config NET_SCH_INGRESS |
| 260 | tristate "Ingress Qdisc" | 257 | tristate "Ingress Qdisc" |
| 261 | depends on NET_SCHED | 258 | depends on NET_SCHED |
| 262 | help | 259 | ---help--- |
| 263 | If you say Y here, you will be able to police incoming bandwidth | 260 | Say Y here if you want to use classifiers for incoming packets. |
| 264 | and drop packets when this bandwidth exceeds your desired rate. | ||
| 265 | If unsure, say Y. | 261 | If unsure, say Y. |
| 266 | 262 | ||
| 267 | To compile this code as a module, choose M here: the | 263 | To compile this code as a module, choose M here: the |
| 268 | module will be called sch_ingress. | 264 | module will be called sch_ingress. |
| 269 | 265 | ||
| 270 | config NET_QOS | 266 | comment "Classification" |
| 271 | bool "QoS support" | ||
| 272 | depends on NET_SCHED | 267 | depends on NET_SCHED |
| 273 | ---help--- | ||
| 274 | Say Y here if you want to include Quality Of Service scheduling | ||
| 275 | features, which means that you will be able to request certain | ||
| 276 | rate-of-flow limits for your network devices. | ||
| 277 | |||
| 278 | This Quality of Service (QoS) support will enable you to use | ||
| 279 | Differentiated Services (diffserv) and Resource Reservation Protocol | ||
| 280 | (RSVP) on your Linux router if you also say Y to "Packet classifier | ||
| 281 | API" and to some classifiers below. Documentation and software is at | ||
| 282 | <http://diffserv.sourceforge.net/>. | ||
| 283 | |||
| 284 | Note that the answer to this question won't directly affect the | ||
| 285 | kernel: saying N will just cause the configurator to skip all | ||
| 286 | the questions about QoS support. | ||
| 287 | |||
| 288 | config NET_ESTIMATOR | ||
| 289 | bool "Rate estimator" | ||
| 290 | depends on NET_QOS | ||
| 291 | help | ||
| 292 | In order for Quality of Service scheduling to work, the current | ||
| 293 | rate-of-flow for a network device has to be estimated; if you say Y | ||
| 294 | here, the kernel will do just that. | ||
| 295 | 268 | ||
| 296 | config NET_CLS | 269 | config NET_CLS |
| 297 | bool "Packet classifier API" | 270 | boolean |
| 298 | depends on NET_SCHED | ||
| 299 | ---help--- | ||
| 300 | The CBQ scheduling algorithm requires that network packets which are | ||
| 301 | scheduled to be sent out over a network device be classified | ||
| 302 | according to some criterion. If you say Y here, you will get a | ||
| 303 | choice of several different packet classifiers with the following | ||
| 304 | questions. | ||
| 305 | |||
| 306 | This will enable you to use Differentiated Services (diffserv) and | ||
| 307 | Resource Reservation Protocol (RSVP) on your Linux router. | ||
| 308 | Documentation and software is at | ||
| 309 | <http://diffserv.sourceforge.net/>. | ||
| 310 | 271 | ||
| 311 | config NET_CLS_BASIC | 272 | config NET_CLS_BASIC |
| 312 | tristate "Basic classifier" | 273 | tristate "Elementary classification (BASIC)" |
| 313 | depends on NET_CLS | 274 | depends NET_SCHED |
| 275 | select NET_CLS | ||
| 314 | ---help--- | 276 | ---help--- |
| 315 | Say Y here if you want to be able to classify packets using | 277 | Say Y here if you want to be able to classify packets using |
| 316 | only extended matches and actions. | 278 | only extended matches and actions. |
| @@ -319,24 +281,25 @@ config NET_CLS_BASIC | |||
| 319 | module will be called cls_basic. | 281 | module will be called cls_basic. |
| 320 | 282 | ||
| 321 | config NET_CLS_TCINDEX | 283 | config NET_CLS_TCINDEX |
| 322 | tristate "TC index classifier" | 284 | tristate "Traffic-Control Index (TCINDEX)" |
| 323 | depends on NET_CLS | 285 | depends NET_SCHED |
| 324 | help | 286 | select NET_CLS |
| 325 | If you say Y here, you will be able to classify outgoing packets | 287 | ---help--- |
| 326 | according to the tc_index field of the skb. You will want this | 288 | Say Y here if you want to be able to classify packets based on |
| 327 | feature if you want to implement Differentiated Services using | 289 | traffic control indices. You will want this feature if you want |
| 328 | sch_dsmark. If unsure, say Y. | 290 | to implement Differentiated Services together with DSMARK. |
| 329 | 291 | ||
| 330 | To compile this code as a module, choose M here: the | 292 | To compile this code as a module, choose M here: the |
| 331 | module will be called cls_tcindex. | 293 | module will be called cls_tcindex. |
| 332 | 294 | ||
| 333 | config NET_CLS_ROUTE4 | 295 | config NET_CLS_ROUTE4 |
| 334 | tristate "Routing table based classifier" | 296 | tristate "Routing decision (ROUTE)" |
| 335 | depends on NET_CLS | 297 | depends NET_SCHED |
| 336 | select NET_CLS_ROUTE | 298 | select NET_CLS_ROUTE |
| 337 | help | 299 | select NET_CLS |
| 338 | If you say Y here, you will be able to classify outgoing packets | 300 | ---help--- |
| 339 | according to the route table entry they matched. If unsure, say Y. | 301 | If you say Y here, you will be able to classify packets |
| 302 | according to the route table entry they matched. | ||
| 340 | 303 | ||
| 341 | To compile this code as a module, choose M here: the | 304 | To compile this code as a module, choose M here: the |
| 342 | module will be called cls_route. | 305 | module will be called cls_route. |
| @@ -346,58 +309,45 @@ config NET_CLS_ROUTE | |||
| 346 | default n | 309 | default n |
| 347 | 310 | ||
| 348 | config NET_CLS_FW | 311 | config NET_CLS_FW |
| 349 | tristate "Firewall based classifier" | 312 | tristate "Netfilter mark (FW)" |
| 350 | depends on NET_CLS | 313 | depends NET_SCHED |
| 351 | help | 314 | select NET_CLS |
| 352 | If you say Y here, you will be able to classify outgoing packets | 315 | ---help--- |
| 353 | according to firewall criteria you specified. | 316 | If you say Y here, you will be able to classify packets |
| 317 | according to netfilter/firewall marks. | ||
| 354 | 318 | ||
| 355 | To compile this code as a module, choose M here: the | 319 | To compile this code as a module, choose M here: the |
| 356 | module will be called cls_fw. | 320 | module will be called cls_fw. |
| 357 | 321 | ||
| 358 | config NET_CLS_U32 | 322 | config NET_CLS_U32 |
| 359 | tristate "U32 classifier" | 323 | tristate "Universal 32bit comparisons w/ hashing (U32)" |
| 360 | depends on NET_CLS | 324 | depends NET_SCHED |
| 361 | help | 325 | select NET_CLS |
| 362 | If you say Y here, you will be able to classify outgoing packets | 326 | ---help--- |
| 363 | according to their destination address. If unsure, say Y. | 327 | Say Y here to be able to classify packetes using a universal |
| 328 | 32bit pieces based comparison scheme. | ||
| 364 | 329 | ||
| 365 | To compile this code as a module, choose M here: the | 330 | To compile this code as a module, choose M here: the |
| 366 | module will be called cls_u32. | 331 | module will be called cls_u32. |
| 367 | 332 | ||
| 368 | config CLS_U32_PERF | 333 | config CLS_U32_PERF |
| 369 | bool "U32 classifier performance counters" | 334 | bool "Performance counters support" |
| 370 | depends on NET_CLS_U32 | 335 | depends on NET_CLS_U32 |
| 371 | help | 336 | ---help--- |
| 372 | gathers stats that could be used to tune u32 classifier performance. | 337 | Say Y here to make u32 gather additional statistics useful for |
| 373 | Requires a new iproute2 | 338 | fine tuning u32 classifiers. |
| 374 | You MUST NOT turn this on if you dont have an update iproute2. | ||
| 375 | |||
| 376 | config NET_CLS_IND | ||
| 377 | bool "classify input device (slows things u32/fw) " | ||
| 378 | depends on NET_CLS_U32 || NET_CLS_FW | ||
| 379 | help | ||
| 380 | This option will be killed eventually when a | ||
| 381 | metadata action appears because it slows things a little | ||
| 382 | Available only for u32 and fw classifiers. | ||
| 383 | Requires a new iproute2 | ||
| 384 | You MUST NOT turn this on if you dont have an update iproute2. | ||
| 385 | 339 | ||
| 386 | config CLS_U32_MARK | 340 | config CLS_U32_MARK |
| 387 | bool "Use nfmark as a key in U32 classifier" | 341 | bool "Netfilter marks support" |
| 388 | depends on NET_CLS_U32 && NETFILTER | 342 | depends on NET_CLS_U32 && NETFILTER |
| 389 | help | 343 | ---help--- |
| 390 | This allows you to match mark in a u32 filter. | 344 | Say Y here to be able to use netfilter marks as u32 key. |
| 391 | Example: | ||
| 392 | tc filter add dev eth0 protocol ip parent 1:0 prio 5 u32 \ | ||
| 393 | match mark 0x0090 0xffff \ | ||
| 394 | match ip dst 4.4.4.4 \ | ||
| 395 | flowid 1:90 | ||
| 396 | You must use a new iproute2 to use this feature. | ||
| 397 | 345 | ||
| 398 | config NET_CLS_RSVP | 346 | config NET_CLS_RSVP |
| 399 | tristate "Special RSVP classifier" | 347 | tristate "IPv4 Resource Reservation Protocol (RSVP)" |
| 400 | depends on NET_CLS && NET_QOS | 348 | depends on NET_SCHED |
| 349 | select NET_CLS | ||
| 350 | select NET_ESTIMATOR | ||
| 401 | ---help--- | 351 | ---help--- |
| 402 | The Resource Reservation Protocol (RSVP) permits end systems to | 352 | The Resource Reservation Protocol (RSVP) permits end systems to |
| 403 | request a minimum and maximum data flow rate for a connection; this | 353 | request a minimum and maximum data flow rate for a connection; this |
| @@ -410,31 +360,33 @@ config NET_CLS_RSVP | |||
| 410 | module will be called cls_rsvp. | 360 | module will be called cls_rsvp. |
| 411 | 361 | ||
| 412 | config NET_CLS_RSVP6 | 362 | config NET_CLS_RSVP6 |
| 413 | tristate "Special RSVP classifier for IPv6" | 363 | tristate "IPv6 Resource Reservation Protocol (RSVP6)" |
| 414 | depends on NET_CLS && NET_QOS | 364 | depends on NET_SCHED |
| 365 | select NET_CLS | ||
| 366 | select NET_ESTIMATOR | ||
| 415 | ---help--- | 367 | ---help--- |
| 416 | The Resource Reservation Protocol (RSVP) permits end systems to | 368 | The Resource Reservation Protocol (RSVP) permits end systems to |
| 417 | request a minimum and maximum data flow rate for a connection; this | 369 | request a minimum and maximum data flow rate for a connection; this |
| 418 | is important for real time data such as streaming sound or video. | 370 | is important for real time data such as streaming sound or video. |
| 419 | 371 | ||
| 420 | Say Y here if you want to be able to classify outgoing packets based | 372 | Say Y here if you want to be able to classify outgoing packets based |
| 421 | on their RSVP requests and you are using the new Internet Protocol | 373 | on their RSVP requests and you are using the IPv6. |
| 422 | IPv6 as opposed to the older and more common IPv4. | ||
| 423 | 374 | ||
| 424 | To compile this code as a module, choose M here: the | 375 | To compile this code as a module, choose M here: the |
| 425 | module will be called cls_rsvp6. | 376 | module will be called cls_rsvp6. |
| 426 | 377 | ||
| 427 | config NET_EMATCH | 378 | config NET_EMATCH |
| 428 | bool "Extended Matches" | 379 | bool "Extended Matches" |
| 429 | depends on NET_CLS | 380 | depends NET_SCHED |
| 381 | select NET_CLS | ||
| 430 | ---help--- | 382 | ---help--- |
| 431 | Say Y here if you want to use extended matches on top of classifiers | 383 | Say Y here if you want to use extended matches on top of classifiers |
| 432 | and select the extended matches below. | 384 | and select the extended matches below. |
| 433 | 385 | ||
| 434 | Extended matches are small classification helpers not worth writing | 386 | Extended matches are small classification helpers not worth writing |
| 435 | a separate classifier. | 387 | a separate classifier for. |
| 436 | 388 | ||
| 437 | You must have a recent version of the iproute2 tools in order to use | 389 | A recent version of the iproute2 package is required to use |
| 438 | extended matches. | 390 | extended matches. |
| 439 | 391 | ||
| 440 | config NET_EMATCH_STACK | 392 | config NET_EMATCH_STACK |
| @@ -468,7 +420,7 @@ config NET_EMATCH_NBYTE | |||
| 468 | module will be called em_nbyte. | 420 | module will be called em_nbyte. |
| 469 | 421 | ||
| 470 | config NET_EMATCH_U32 | 422 | config NET_EMATCH_U32 |
| 471 | tristate "U32 hashing key" | 423 | tristate "U32 key" |
| 472 | depends on NET_EMATCH | 424 | depends on NET_EMATCH |
| 473 | ---help--- | 425 | ---help--- |
| 474 | Say Y here if you want to be able to classify packets using | 426 | Say Y here if you want to be able to classify packets using |
| @@ -496,76 +448,120 @@ config NET_EMATCH_TEXT | |||
| 496 | select TEXTSEARCH_BM | 448 | select TEXTSEARCH_BM |
| 497 | select TEXTSEARCH_FSM | 449 | select TEXTSEARCH_FSM |
| 498 | ---help--- | 450 | ---help--- |
| 499 | Say Y here if you want to be ablt to classify packets based on | 451 | Say Y here if you want to be able to classify packets based on |
| 500 | textsearch comparisons. | 452 | textsearch comparisons. |
| 501 | 453 | ||
| 502 | To compile this code as a module, choose M here: the | 454 | To compile this code as a module, choose M here: the |
| 503 | module will be called em_text. | 455 | module will be called em_text. |
| 504 | 456 | ||
| 505 | config NET_CLS_ACT | 457 | config NET_CLS_ACT |
| 506 | bool "Packet ACTION" | 458 | bool "Actions" |
| 507 | depends on EXPERIMENTAL && NET_CLS && NET_QOS | 459 | depends on EXPERIMENTAL && NET_SCHED |
| 460 | select NET_ESTIMATOR | ||
| 508 | ---help--- | 461 | ---help--- |
| 509 | This option requires you have a new iproute2. It enables | 462 | Say Y here if you want to use traffic control actions. Actions |
| 510 | tc extensions which can be used with tc classifiers. | 463 | get attached to classifiers and are invoked after a successful |
| 511 | You MUST NOT turn this on if you dont have an update iproute2. | 464 | classification. They are used to overwrite the classification |
| 465 | result, instantly drop or redirect packets, etc. | ||
| 466 | |||
| 467 | A recent version of the iproute2 package is required to use | ||
| 468 | extended matches. | ||
| 512 | 469 | ||
| 513 | config NET_ACT_POLICE | 470 | config NET_ACT_POLICE |
| 514 | tristate "Policing Actions" | 471 | tristate "Traffic Policing" |
| 515 | depends on NET_CLS_ACT | 472 | depends on NET_CLS_ACT |
| 516 | ---help--- | 473 | ---help--- |
| 517 | If you are using a newer iproute2 select this one, otherwise use one | 474 | Say Y here if you want to do traffic policing, i.e. strict |
| 518 | below to select a policer. | 475 | bandwidth limiting. This action replaces the existing policing |
| 519 | You MUST NOT turn this on if you dont have an update iproute2. | 476 | module. |
| 477 | |||
| 478 | To compile this code as a module, choose M here: the | ||
| 479 | module will be called police. | ||
| 520 | 480 | ||
| 521 | config NET_ACT_GACT | 481 | config NET_ACT_GACT |
| 522 | tristate "generic Actions" | 482 | tristate "Generic actions" |
| 523 | depends on NET_CLS_ACT | 483 | depends on NET_CLS_ACT |
| 524 | ---help--- | 484 | ---help--- |
| 525 | You must have new iproute2 to use this feature. | 485 | Say Y here to take generic actions such as dropping and |
| 526 | This adds simple filtering actions like drop, accept etc. | 486 | accepting packets. |
| 487 | |||
| 488 | To compile this code as a module, choose M here: the | ||
| 489 | module will be called gact. | ||
| 527 | 490 | ||
| 528 | config GACT_PROB | 491 | config GACT_PROB |
| 529 | bool "generic Actions probability" | 492 | bool "Probability support" |
| 530 | depends on NET_ACT_GACT | 493 | depends on NET_ACT_GACT |
| 531 | ---help--- | 494 | ---help--- |
| 532 | Allows generic actions to be randomly or deterministically used. | 495 | Say Y here to use the generic action randomly or deterministically. |
| 533 | 496 | ||
| 534 | config NET_ACT_MIRRED | 497 | config NET_ACT_MIRRED |
| 535 | tristate "Packet In/Egress redirecton/mirror Actions" | 498 | tristate "Redirecting and Mirroring" |
| 536 | depends on NET_CLS_ACT | 499 | depends on NET_CLS_ACT |
| 537 | ---help--- | 500 | ---help--- |
| 538 | requires new iproute2 | 501 | Say Y here to allow packets to be mirrored or redirected to |
| 539 | This allows packets to be mirrored or redirected to netdevices | 502 | other devices. |
| 503 | |||
| 504 | To compile this code as a module, choose M here: the | ||
| 505 | module will be called mirred. | ||
| 540 | 506 | ||
| 541 | config NET_ACT_IPT | 507 | config NET_ACT_IPT |
| 542 | tristate "iptables Actions" | 508 | tristate "IPtables targets" |
| 543 | depends on NET_CLS_ACT && NETFILTER && IP_NF_IPTABLES | 509 | depends on NET_CLS_ACT && NETFILTER && IP_NF_IPTABLES |
| 544 | ---help--- | 510 | ---help--- |
| 545 | requires new iproute2 | 511 | Say Y here to be able to invoke iptables targets after succesful |
| 546 | This allows iptables targets to be used by tc filters | 512 | classification. |
| 513 | |||
| 514 | To compile this code as a module, choose M here: the | ||
| 515 | module will be called ipt. | ||
| 547 | 516 | ||
| 548 | config NET_ACT_PEDIT | 517 | config NET_ACT_PEDIT |
| 549 | tristate "Generic Packet Editor Actions" | 518 | tristate "Packet Editing" |
| 550 | depends on NET_CLS_ACT | 519 | depends on NET_CLS_ACT |
| 551 | ---help--- | 520 | ---help--- |
| 552 | requires new iproute2 | 521 | Say Y here if you want to mangle the content of packets. |
| 553 | This allows for packets to be generically edited | ||
| 554 | 522 | ||
| 555 | config NET_CLS_POLICE | 523 | To compile this code as a module, choose M here: the |
| 556 | bool "Traffic policing (needed for in/egress)" | 524 | module will be called pedit. |
| 557 | depends on NET_CLS && NET_QOS && NET_CLS_ACT!=y | ||
| 558 | help | ||
| 559 | Say Y to support traffic policing (bandwidth limits). Needed for | ||
| 560 | ingress and egress rate limiting. | ||
| 561 | 525 | ||
| 562 | config NET_ACT_SIMP | 526 | config NET_ACT_SIMP |
| 563 | tristate "Simple action" | 527 | tristate "Simple Example (Debug)" |
| 564 | depends on NET_CLS_ACT | 528 | depends on NET_CLS_ACT |
| 565 | ---help--- | 529 | ---help--- |
| 566 | You must have new iproute2 to use this feature. | 530 | Say Y here to add a simple action for demonstration purposes. |
| 567 | This adds a very simple action for demonstration purposes | 531 | It is meant as an example and for debugging purposes. It will |
| 568 | The idea is to give action authors a basic example to look at. | 532 | print a configured policy string followed by the packet count |
| 569 | All this action will do is print on the console the configured | 533 | to the console for every packet that passes by. |
| 570 | policy string followed by _ then packet count. | 534 | |
| 535 | If unsure, say N. | ||
| 536 | |||
| 537 | To compile this code as a module, choose M here: the | ||
| 538 | module will be called simple. | ||
| 539 | |||
| 540 | config NET_CLS_POLICE | ||
| 541 | bool "Traffic Policing (obsolete)" | ||
| 542 | depends on NET_SCHED && NET_CLS_ACT!=y | ||
| 543 | select NET_ESTIMATOR | ||
| 544 | ---help--- | ||
| 545 | Say Y here if you want to do traffic policing, i.e. strict | ||
| 546 | bandwidth limiting. This option is obsoleted by the traffic | ||
| 547 | policer implemented as action, it stays here for compatibility | ||
| 548 | reasons. | ||
| 549 | |||
| 550 | config NET_CLS_IND | ||
| 551 | bool "Incoming device classification" | ||
| 552 | depends on NET_SCHED && (NET_CLS_U32 || NET_CLS_FW) | ||
| 553 | ---help--- | ||
| 554 | Say Y here to extend the u32 and fw classifier to support | ||
| 555 | classification based on the incoming device. This option is | ||
| 556 | likely to disappear in favour of the metadata ematch. | ||
| 557 | |||
| 558 | config NET_ESTIMATOR | ||
| 559 | bool "Rate estimator" | ||
| 560 | depends on NET_SCHED | ||
| 561 | ---help--- | ||
| 562 | Say Y here to allow using rate estimators to estimate the current | ||
| 563 | rate-of-flow for network devices, queues, etc. This module is | ||
| 564 | automaticaly selected if needed but can be selected manually for | ||
| 565 | statstical purposes. | ||
| 571 | 566 | ||
| 567 | endmenu | ||
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index 10e82ec2ebd3..660c61bdf164 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c | |||
| @@ -554,7 +554,7 @@ struct sctp_chunk *sctp_make_datafrag_empty(struct sctp_association *asoc, | |||
| 554 | dp.ppid = sinfo->sinfo_ppid; | 554 | dp.ppid = sinfo->sinfo_ppid; |
| 555 | 555 | ||
| 556 | /* Set the flags for an unordered send. */ | 556 | /* Set the flags for an unordered send. */ |
| 557 | if (sinfo->sinfo_flags & MSG_UNORDERED) { | 557 | if (sinfo->sinfo_flags & SCTP_UNORDERED) { |
| 558 | flags |= SCTP_DATA_UNORDERED; | 558 | flags |= SCTP_DATA_UNORDERED; |
| 559 | dp.ssn = 0; | 559 | dp.ssn = 0; |
| 560 | } else | 560 | } else |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 02e068d3450d..b529af5e6f2a 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
| @@ -1010,6 +1010,19 @@ static int __sctp_connect(struct sock* sk, | |||
| 1010 | err = -EAGAIN; | 1010 | err = -EAGAIN; |
| 1011 | goto out_free; | 1011 | goto out_free; |
| 1012 | } | 1012 | } |
| 1013 | } else { | ||
| 1014 | /* | ||
| 1015 | * If an unprivileged user inherits a 1-many | ||
| 1016 | * style socket with open associations on a | ||
| 1017 | * privileged port, it MAY be permitted to | ||
| 1018 | * accept new associations, but it SHOULD NOT | ||
| 1019 | * be permitted to open new associations. | ||
| 1020 | */ | ||
| 1021 | if (ep->base.bind_addr.port < PROT_SOCK && | ||
| 1022 | !capable(CAP_NET_BIND_SERVICE)) { | ||
| 1023 | err = -EACCES; | ||
| 1024 | goto out_free; | ||
| 1025 | } | ||
| 1013 | } | 1026 | } |
| 1014 | 1027 | ||
| 1015 | scope = sctp_scope(&to); | 1028 | scope = sctp_scope(&to); |
| @@ -1389,27 +1402,27 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
| 1389 | SCTP_DEBUG_PRINTK("msg_len: %zu, sinfo_flags: 0x%x\n", | 1402 | SCTP_DEBUG_PRINTK("msg_len: %zu, sinfo_flags: 0x%x\n", |
| 1390 | msg_len, sinfo_flags); | 1403 | msg_len, sinfo_flags); |
| 1391 | 1404 | ||
| 1392 | /* MSG_EOF or MSG_ABORT cannot be set on a TCP-style socket. */ | 1405 | /* SCTP_EOF or SCTP_ABORT cannot be set on a TCP-style socket. */ |
| 1393 | if (sctp_style(sk, TCP) && (sinfo_flags & (MSG_EOF | MSG_ABORT))) { | 1406 | if (sctp_style(sk, TCP) && (sinfo_flags & (SCTP_EOF | SCTP_ABORT))) { |
| 1394 | err = -EINVAL; | 1407 | err = -EINVAL; |
| 1395 | goto out_nounlock; | 1408 | goto out_nounlock; |
| 1396 | } | 1409 | } |
| 1397 | 1410 | ||
| 1398 | /* If MSG_EOF is set, no data can be sent. Disallow sending zero | 1411 | /* If SCTP_EOF is set, no data can be sent. Disallow sending zero |
| 1399 | * length messages when MSG_EOF|MSG_ABORT is not set. | 1412 | * length messages when SCTP_EOF|SCTP_ABORT is not set. |
| 1400 | * If MSG_ABORT is set, the message length could be non zero with | 1413 | * If SCTP_ABORT is set, the message length could be non zero with |
| 1401 | * the msg_iov set to the user abort reason. | 1414 | * the msg_iov set to the user abort reason. |
| 1402 | */ | 1415 | */ |
| 1403 | if (((sinfo_flags & MSG_EOF) && (msg_len > 0)) || | 1416 | if (((sinfo_flags & SCTP_EOF) && (msg_len > 0)) || |
| 1404 | (!(sinfo_flags & (MSG_EOF|MSG_ABORT)) && (msg_len == 0))) { | 1417 | (!(sinfo_flags & (SCTP_EOF|SCTP_ABORT)) && (msg_len == 0))) { |
| 1405 | err = -EINVAL; | 1418 | err = -EINVAL; |
| 1406 | goto out_nounlock; | 1419 | goto out_nounlock; |
| 1407 | } | 1420 | } |
| 1408 | 1421 | ||
| 1409 | /* If MSG_ADDR_OVER is set, there must be an address | 1422 | /* If SCTP_ADDR_OVER is set, there must be an address |
| 1410 | * specified in msg_name. | 1423 | * specified in msg_name. |
| 1411 | */ | 1424 | */ |
| 1412 | if ((sinfo_flags & MSG_ADDR_OVER) && (!msg->msg_name)) { | 1425 | if ((sinfo_flags & SCTP_ADDR_OVER) && (!msg->msg_name)) { |
| 1413 | err = -EINVAL; | 1426 | err = -EINVAL; |
| 1414 | goto out_nounlock; | 1427 | goto out_nounlock; |
| 1415 | } | 1428 | } |
| @@ -1458,14 +1471,14 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
| 1458 | goto out_unlock; | 1471 | goto out_unlock; |
| 1459 | } | 1472 | } |
| 1460 | 1473 | ||
| 1461 | if (sinfo_flags & MSG_EOF) { | 1474 | if (sinfo_flags & SCTP_EOF) { |
| 1462 | SCTP_DEBUG_PRINTK("Shutting down association: %p\n", | 1475 | SCTP_DEBUG_PRINTK("Shutting down association: %p\n", |
| 1463 | asoc); | 1476 | asoc); |
| 1464 | sctp_primitive_SHUTDOWN(asoc, NULL); | 1477 | sctp_primitive_SHUTDOWN(asoc, NULL); |
| 1465 | err = 0; | 1478 | err = 0; |
| 1466 | goto out_unlock; | 1479 | goto out_unlock; |
| 1467 | } | 1480 | } |
| 1468 | if (sinfo_flags & MSG_ABORT) { | 1481 | if (sinfo_flags & SCTP_ABORT) { |
| 1469 | SCTP_DEBUG_PRINTK("Aborting association: %p\n", asoc); | 1482 | SCTP_DEBUG_PRINTK("Aborting association: %p\n", asoc); |
| 1470 | sctp_primitive_ABORT(asoc, msg); | 1483 | sctp_primitive_ABORT(asoc, msg); |
| 1471 | err = 0; | 1484 | err = 0; |
| @@ -1477,7 +1490,7 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
| 1477 | if (!asoc) { | 1490 | if (!asoc) { |
| 1478 | SCTP_DEBUG_PRINTK("There is no association yet.\n"); | 1491 | SCTP_DEBUG_PRINTK("There is no association yet.\n"); |
| 1479 | 1492 | ||
| 1480 | if (sinfo_flags & (MSG_EOF | MSG_ABORT)) { | 1493 | if (sinfo_flags & (SCTP_EOF | SCTP_ABORT)) { |
| 1481 | err = -EINVAL; | 1494 | err = -EINVAL; |
| 1482 | goto out_unlock; | 1495 | goto out_unlock; |
| 1483 | } | 1496 | } |
| @@ -1515,6 +1528,19 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
| 1515 | err = -EAGAIN; | 1528 | err = -EAGAIN; |
| 1516 | goto out_unlock; | 1529 | goto out_unlock; |
| 1517 | } | 1530 | } |
| 1531 | } else { | ||
| 1532 | /* | ||
| 1533 | * If an unprivileged user inherits a one-to-many | ||
| 1534 | * style socket with open associations on a privileged | ||
| 1535 | * port, it MAY be permitted to accept new associations, | ||
| 1536 | * but it SHOULD NOT be permitted to open new | ||
| 1537 | * associations. | ||
| 1538 | */ | ||
| 1539 | if (ep->base.bind_addr.port < PROT_SOCK && | ||
| 1540 | !capable(CAP_NET_BIND_SERVICE)) { | ||
| 1541 | err = -EACCES; | ||
| 1542 | goto out_unlock; | ||
| 1543 | } | ||
| 1518 | } | 1544 | } |
| 1519 | 1545 | ||
| 1520 | scope = sctp_scope(&to); | 1546 | scope = sctp_scope(&to); |
| @@ -1611,10 +1637,10 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
| 1611 | 1637 | ||
| 1612 | /* If an address is passed with the sendto/sendmsg call, it is used | 1638 | /* If an address is passed with the sendto/sendmsg call, it is used |
| 1613 | * to override the primary destination address in the TCP model, or | 1639 | * to override the primary destination address in the TCP model, or |
| 1614 | * when MSG_ADDR_OVER flag is set in the UDP model. | 1640 | * when SCTP_ADDR_OVER flag is set in the UDP model. |
| 1615 | */ | 1641 | */ |
| 1616 | if ((sctp_style(sk, TCP) && msg_name) || | 1642 | if ((sctp_style(sk, TCP) && msg_name) || |
| 1617 | (sinfo_flags & MSG_ADDR_OVER)) { | 1643 | (sinfo_flags & SCTP_ADDR_OVER)) { |
| 1618 | chunk_tp = sctp_assoc_lookup_paddr(asoc, &to); | 1644 | chunk_tp = sctp_assoc_lookup_paddr(asoc, &to); |
| 1619 | if (!chunk_tp) { | 1645 | if (!chunk_tp) { |
| 1620 | err = -EINVAL; | 1646 | err = -EINVAL; |
| @@ -2306,16 +2332,14 @@ static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, int optl | |||
| 2306 | return -EINVAL; | 2332 | return -EINVAL; |
| 2307 | if (get_user(val, (int __user *)optval)) | 2333 | if (get_user(val, (int __user *)optval)) |
| 2308 | return -EFAULT; | 2334 | return -EFAULT; |
| 2309 | if ((val < 8) || (val > SCTP_MAX_CHUNK_LEN)) | 2335 | if ((val != 0) && ((val < 8) || (val > SCTP_MAX_CHUNK_LEN))) |
| 2310 | return -EINVAL; | 2336 | return -EINVAL; |
| 2311 | sp->user_frag = val; | 2337 | sp->user_frag = val; |
| 2312 | 2338 | ||
| 2313 | if (val) { | 2339 | /* Update the frag_point of the existing associations. */ |
| 2314 | /* Update the frag_point of the existing associations. */ | 2340 | list_for_each(pos, &(sp->ep->asocs)) { |
| 2315 | list_for_each(pos, &(sp->ep->asocs)) { | 2341 | asoc = list_entry(pos, struct sctp_association, asocs); |
| 2316 | asoc = list_entry(pos, struct sctp_association, asocs); | 2342 | asoc->frag_point = sctp_frag_point(sp, asoc->pmtu); |
| 2317 | asoc->frag_point = sctp_frag_point(sp, asoc->pmtu); | ||
| 2318 | } | ||
| 2319 | } | 2343 | } |
| 2320 | 2344 | ||
| 2321 | return 0; | 2345 | return 0; |
| @@ -2384,14 +2408,14 @@ static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char __user *optva | |||
| 2384 | static int sctp_setsockopt_adaption_layer(struct sock *sk, char __user *optval, | 2408 | static int sctp_setsockopt_adaption_layer(struct sock *sk, char __user *optval, |
| 2385 | int optlen) | 2409 | int optlen) |
| 2386 | { | 2410 | { |
| 2387 | __u32 val; | 2411 | struct sctp_setadaption adaption; |
| 2388 | 2412 | ||
| 2389 | if (optlen < sizeof(__u32)) | 2413 | if (optlen != sizeof(struct sctp_setadaption)) |
| 2390 | return -EINVAL; | 2414 | return -EINVAL; |
| 2391 | if (copy_from_user(&val, optval, sizeof(__u32))) | 2415 | if (copy_from_user(&adaption, optval, optlen)) |
| 2392 | return -EFAULT; | 2416 | return -EFAULT; |
| 2393 | 2417 | ||
| 2394 | sctp_sk(sk)->adaption_ind = val; | 2418 | sctp_sk(sk)->adaption_ind = adaption.ssb_adaption_ind; |
| 2395 | 2419 | ||
| 2396 | return 0; | 2420 | return 0; |
| 2397 | } | 2421 | } |
| @@ -3672,17 +3696,15 @@ static int sctp_getsockopt_primary_addr(struct sock *sk, int len, | |||
| 3672 | static int sctp_getsockopt_adaption_layer(struct sock *sk, int len, | 3696 | static int sctp_getsockopt_adaption_layer(struct sock *sk, int len, |
| 3673 | char __user *optval, int __user *optlen) | 3697 | char __user *optval, int __user *optlen) |
| 3674 | { | 3698 | { |
| 3675 | __u32 val; | 3699 | struct sctp_setadaption adaption; |
| 3676 | 3700 | ||
| 3677 | if (len < sizeof(__u32)) | 3701 | if (len != sizeof(struct sctp_setadaption)) |
| 3678 | return -EINVAL; | 3702 | return -EINVAL; |
| 3679 | 3703 | ||
| 3680 | len = sizeof(__u32); | 3704 | adaption.ssb_adaption_ind = sctp_sk(sk)->adaption_ind; |
| 3681 | val = sctp_sk(sk)->adaption_ind; | 3705 | if (copy_to_user(optval, &adaption, len)) |
| 3682 | if (put_user(len, optlen)) | ||
| 3683 | return -EFAULT; | ||
| 3684 | if (copy_to_user(optval, &val, len)) | ||
| 3685 | return -EFAULT; | 3706 | return -EFAULT; |
| 3707 | |||
| 3686 | return 0; | 3708 | return 0; |
| 3687 | } | 3709 | } |
| 3688 | 3710 | ||
| @@ -4640,8 +4662,8 @@ SCTP_STATIC int sctp_msghdr_parse(const struct msghdr *msg, | |||
| 4640 | 4662 | ||
| 4641 | /* Minimally, validate the sinfo_flags. */ | 4663 | /* Minimally, validate the sinfo_flags. */ |
| 4642 | if (cmsgs->info->sinfo_flags & | 4664 | if (cmsgs->info->sinfo_flags & |
| 4643 | ~(MSG_UNORDERED | MSG_ADDR_OVER | | 4665 | ~(SCTP_UNORDERED | SCTP_ADDR_OVER | |
| 4644 | MSG_ABORT | MSG_EOF)) | 4666 | SCTP_ABORT | SCTP_EOF)) |
| 4645 | return -EINVAL; | 4667 | return -EINVAL; |
| 4646 | break; | 4668 | break; |
| 4647 | 4669 | ||
diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c index 057e7fac3af0..e049f41faa47 100644 --- a/net/sctp/ulpevent.c +++ b/net/sctp/ulpevent.c | |||
| @@ -698,7 +698,7 @@ struct sctp_ulpevent *sctp_ulpevent_make_rcvmsg(struct sctp_association *asoc, | |||
| 698 | event->ssn = ntohs(chunk->subh.data_hdr->ssn); | 698 | event->ssn = ntohs(chunk->subh.data_hdr->ssn); |
| 699 | event->ppid = chunk->subh.data_hdr->ppid; | 699 | event->ppid = chunk->subh.data_hdr->ppid; |
| 700 | if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED) { | 700 | if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED) { |
| 701 | event->flags |= MSG_UNORDERED; | 701 | event->flags |= SCTP_UNORDERED; |
| 702 | event->cumtsn = sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map); | 702 | event->cumtsn = sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map); |
| 703 | } | 703 | } |
| 704 | event->tsn = ntohl(chunk->subh.data_hdr->tsn); | 704 | event->tsn = ntohl(chunk->subh.data_hdr->tsn); |
| @@ -824,7 +824,7 @@ void sctp_ulpevent_read_sndrcvinfo(const struct sctp_ulpevent *event, | |||
| 824 | * | 824 | * |
| 825 | * recvmsg() flags: | 825 | * recvmsg() flags: |
| 826 | * | 826 | * |
| 827 | * MSG_UNORDERED - This flag is present when the message was sent | 827 | * SCTP_UNORDERED - This flag is present when the message was sent |
| 828 | * non-ordered. | 828 | * non-ordered. |
| 829 | */ | 829 | */ |
| 830 | sinfo.sinfo_flags = event->flags; | 830 | sinfo.sinfo_flags = event->flags; |
| @@ -839,7 +839,7 @@ void sctp_ulpevent_read_sndrcvinfo(const struct sctp_ulpevent *event, | |||
| 839 | * This field will hold the current cumulative TSN as | 839 | * This field will hold the current cumulative TSN as |
| 840 | * known by the underlying SCTP layer. Note this field is | 840 | * known by the underlying SCTP layer. Note this field is |
| 841 | * ignored when sending and only valid for a receive | 841 | * ignored when sending and only valid for a receive |
| 842 | * operation when sinfo_flags are set to MSG_UNORDERED. | 842 | * operation when sinfo_flags are set to SCTP_UNORDERED. |
| 843 | */ | 843 | */ |
| 844 | sinfo.sinfo_cumtsn = event->cumtsn; | 844 | sinfo.sinfo_cumtsn = event->cumtsn; |
| 845 | /* sinfo_assoc_id: sizeof (sctp_assoc_t) | 845 | /* sinfo_assoc_id: sizeof (sctp_assoc_t) |
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c index a415d99c394d..8c7756036e95 100644 --- a/net/sunrpc/auth.c +++ b/net/sunrpc/auth.c | |||
| @@ -299,11 +299,10 @@ put_rpccred(struct rpc_cred *cred) | |||
| 299 | void | 299 | void |
| 300 | rpcauth_unbindcred(struct rpc_task *task) | 300 | rpcauth_unbindcred(struct rpc_task *task) |
| 301 | { | 301 | { |
| 302 | struct rpc_auth *auth = task->tk_auth; | ||
| 303 | struct rpc_cred *cred = task->tk_msg.rpc_cred; | 302 | struct rpc_cred *cred = task->tk_msg.rpc_cred; |
| 304 | 303 | ||
| 305 | dprintk("RPC: %4d releasing %s cred %p\n", | 304 | dprintk("RPC: %4d releasing %s cred %p\n", |
| 306 | task->tk_pid, auth->au_ops->au_name, cred); | 305 | task->tk_pid, task->tk_auth->au_ops->au_name, cred); |
| 307 | 306 | ||
| 308 | put_rpccred(cred); | 307 | put_rpccred(cred); |
| 309 | task->tk_msg.rpc_cred = NULL; | 308 | task->tk_msg.rpc_cred = NULL; |
| @@ -312,22 +311,22 @@ rpcauth_unbindcred(struct rpc_task *task) | |||
| 312 | u32 * | 311 | u32 * |
| 313 | rpcauth_marshcred(struct rpc_task *task, u32 *p) | 312 | rpcauth_marshcred(struct rpc_task *task, u32 *p) |
| 314 | { | 313 | { |
| 315 | struct rpc_auth *auth = task->tk_auth; | ||
| 316 | struct rpc_cred *cred = task->tk_msg.rpc_cred; | 314 | struct rpc_cred *cred = task->tk_msg.rpc_cred; |
| 317 | 315 | ||
| 318 | dprintk("RPC: %4d marshaling %s cred %p\n", | 316 | dprintk("RPC: %4d marshaling %s cred %p\n", |
| 319 | task->tk_pid, auth->au_ops->au_name, cred); | 317 | task->tk_pid, task->tk_auth->au_ops->au_name, cred); |
| 318 | |||
| 320 | return cred->cr_ops->crmarshal(task, p); | 319 | return cred->cr_ops->crmarshal(task, p); |
| 321 | } | 320 | } |
| 322 | 321 | ||
| 323 | u32 * | 322 | u32 * |
| 324 | rpcauth_checkverf(struct rpc_task *task, u32 *p) | 323 | rpcauth_checkverf(struct rpc_task *task, u32 *p) |
| 325 | { | 324 | { |
| 326 | struct rpc_auth *auth = task->tk_auth; | ||
| 327 | struct rpc_cred *cred = task->tk_msg.rpc_cred; | 325 | struct rpc_cred *cred = task->tk_msg.rpc_cred; |
| 328 | 326 | ||
| 329 | dprintk("RPC: %4d validating %s cred %p\n", | 327 | dprintk("RPC: %4d validating %s cred %p\n", |
| 330 | task->tk_pid, auth->au_ops->au_name, cred); | 328 | task->tk_pid, task->tk_auth->au_ops->au_name, cred); |
| 329 | |||
| 331 | return cred->cr_ops->crvalidate(task, p); | 330 | return cred->cr_ops->crvalidate(task, p); |
| 332 | } | 331 | } |
| 333 | 332 | ||
| @@ -363,12 +362,12 @@ rpcauth_unwrap_resp(struct rpc_task *task, kxdrproc_t decode, void *rqstp, | |||
| 363 | int | 362 | int |
| 364 | rpcauth_refreshcred(struct rpc_task *task) | 363 | rpcauth_refreshcred(struct rpc_task *task) |
| 365 | { | 364 | { |
| 366 | struct rpc_auth *auth = task->tk_auth; | ||
| 367 | struct rpc_cred *cred = task->tk_msg.rpc_cred; | 365 | struct rpc_cred *cred = task->tk_msg.rpc_cred; |
| 368 | int err; | 366 | int err; |
| 369 | 367 | ||
| 370 | dprintk("RPC: %4d refreshing %s cred %p\n", | 368 | dprintk("RPC: %4d refreshing %s cred %p\n", |
| 371 | task->tk_pid, auth->au_ops->au_name, cred); | 369 | task->tk_pid, task->tk_auth->au_ops->au_name, cred); |
| 370 | |||
| 372 | err = cred->cr_ops->crrefresh(task); | 371 | err = cred->cr_ops->crrefresh(task); |
| 373 | if (err < 0) | 372 | if (err < 0) |
| 374 | task->tk_status = err; | 373 | task->tk_status = err; |
diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c index 3f3d5437f02d..97c981fa6b8e 100644 --- a/net/sunrpc/auth_gss/gss_krb5_crypto.c +++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c | |||
| @@ -37,7 +37,7 @@ | |||
| 37 | #include <linux/types.h> | 37 | #include <linux/types.h> |
| 38 | #include <linux/mm.h> | 38 | #include <linux/mm.h> |
| 39 | #include <linux/slab.h> | 39 | #include <linux/slab.h> |
| 40 | #include <asm/scatterlist.h> | 40 | #include <linux/scatterlist.h> |
| 41 | #include <linux/crypto.h> | 41 | #include <linux/crypto.h> |
| 42 | #include <linux/highmem.h> | 42 | #include <linux/highmem.h> |
| 43 | #include <linux/pagemap.h> | 43 | #include <linux/pagemap.h> |
| @@ -75,9 +75,7 @@ krb5_encrypt( | |||
| 75 | memcpy(local_iv, iv, crypto_tfm_alg_ivsize(tfm)); | 75 | memcpy(local_iv, iv, crypto_tfm_alg_ivsize(tfm)); |
| 76 | 76 | ||
| 77 | memcpy(out, in, length); | 77 | memcpy(out, in, length); |
| 78 | sg[0].page = virt_to_page(out); | 78 | sg_set_buf(sg, out, length); |
| 79 | sg[0].offset = offset_in_page(out); | ||
| 80 | sg[0].length = length; | ||
| 81 | 79 | ||
| 82 | ret = crypto_cipher_encrypt_iv(tfm, sg, sg, length, local_iv); | 80 | ret = crypto_cipher_encrypt_iv(tfm, sg, sg, length, local_iv); |
| 83 | 81 | ||
| @@ -117,9 +115,7 @@ krb5_decrypt( | |||
| 117 | memcpy(local_iv,iv, crypto_tfm_alg_ivsize(tfm)); | 115 | memcpy(local_iv,iv, crypto_tfm_alg_ivsize(tfm)); |
| 118 | 116 | ||
| 119 | memcpy(out, in, length); | 117 | memcpy(out, in, length); |
| 120 | sg[0].page = virt_to_page(out); | 118 | sg_set_buf(sg, out, length); |
| 121 | sg[0].offset = offset_in_page(out); | ||
| 122 | sg[0].length = length; | ||
| 123 | 119 | ||
| 124 | ret = crypto_cipher_decrypt_iv(tfm, sg, sg, length, local_iv); | 120 | ret = crypto_cipher_decrypt_iv(tfm, sg, sg, length, local_iv); |
| 125 | 121 | ||
| @@ -132,13 +128,6 @@ out: | |||
| 132 | 128 | ||
| 133 | EXPORT_SYMBOL(krb5_decrypt); | 129 | EXPORT_SYMBOL(krb5_decrypt); |
| 134 | 130 | ||
| 135 | static void | ||
| 136 | buf_to_sg(struct scatterlist *sg, char *ptr, int len) { | ||
| 137 | sg->page = virt_to_page(ptr); | ||
| 138 | sg->offset = offset_in_page(ptr); | ||
| 139 | sg->length = len; | ||
| 140 | } | ||
| 141 | |||
| 142 | static int | 131 | static int |
| 143 | process_xdr_buf(struct xdr_buf *buf, int offset, int len, | 132 | process_xdr_buf(struct xdr_buf *buf, int offset, int len, |
| 144 | int (*actor)(struct scatterlist *, void *), void *data) | 133 | int (*actor)(struct scatterlist *, void *), void *data) |
| @@ -152,7 +141,7 @@ process_xdr_buf(struct xdr_buf *buf, int offset, int len, | |||
| 152 | thislen = buf->head[0].iov_len - offset; | 141 | thislen = buf->head[0].iov_len - offset; |
| 153 | if (thislen > len) | 142 | if (thislen > len) |
| 154 | thislen = len; | 143 | thislen = len; |
| 155 | buf_to_sg(sg, buf->head[0].iov_base + offset, thislen); | 144 | sg_set_buf(sg, buf->head[0].iov_base + offset, thislen); |
| 156 | ret = actor(sg, data); | 145 | ret = actor(sg, data); |
| 157 | if (ret) | 146 | if (ret) |
| 158 | goto out; | 147 | goto out; |
| @@ -195,7 +184,7 @@ process_xdr_buf(struct xdr_buf *buf, int offset, int len, | |||
| 195 | thislen = buf->tail[0].iov_len - offset; | 184 | thislen = buf->tail[0].iov_len - offset; |
| 196 | if (thislen > len) | 185 | if (thislen > len) |
| 197 | thislen = len; | 186 | thislen = len; |
| 198 | buf_to_sg(sg, buf->tail[0].iov_base + offset, thislen); | 187 | sg_set_buf(sg, buf->tail[0].iov_base + offset, thislen); |
| 199 | ret = actor(sg, data); | 188 | ret = actor(sg, data); |
| 200 | len -= thislen; | 189 | len -= thislen; |
| 201 | } | 190 | } |
| @@ -241,7 +230,7 @@ make_checksum(s32 cksumtype, char *header, int hdrlen, struct xdr_buf *body, | |||
| 241 | goto out; | 230 | goto out; |
| 242 | 231 | ||
| 243 | crypto_digest_init(tfm); | 232 | crypto_digest_init(tfm); |
| 244 | buf_to_sg(sg, header, hdrlen); | 233 | sg_set_buf(sg, header, hdrlen); |
| 245 | crypto_digest_update(tfm, sg, 1); | 234 | crypto_digest_update(tfm, sg, 1); |
| 246 | process_xdr_buf(body, body_offset, body->len - body_offset, | 235 | process_xdr_buf(body, body_offset, body->len - body_offset, |
| 247 | checksummer, tfm); | 236 | checksummer, tfm); |
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c index 2387e7b823ff..a03d4b600c92 100644 --- a/net/sunrpc/sunrpc_syms.c +++ b/net/sunrpc/sunrpc_syms.c | |||
| @@ -63,8 +63,6 @@ EXPORT_SYMBOL(rpc_mkpipe); | |||
| 63 | /* Client transport */ | 63 | /* Client transport */ |
| 64 | EXPORT_SYMBOL(xprt_create_proto); | 64 | EXPORT_SYMBOL(xprt_create_proto); |
| 65 | EXPORT_SYMBOL(xprt_set_timeout); | 65 | EXPORT_SYMBOL(xprt_set_timeout); |
| 66 | EXPORT_SYMBOL(xprt_udp_slot_table_entries); | ||
| 67 | EXPORT_SYMBOL(xprt_tcp_slot_table_entries); | ||
| 68 | 66 | ||
| 69 | /* Client credential cache */ | 67 | /* Client credential cache */ |
| 70 | EXPORT_SYMBOL(rpcauth_register); | 68 | EXPORT_SYMBOL(rpcauth_register); |
diff --git a/net/sunrpc/sysctl.c b/net/sunrpc/sysctl.c index d0c9f460e411..1065904841fd 100644 --- a/net/sunrpc/sysctl.c +++ b/net/sunrpc/sysctl.c | |||
| @@ -119,13 +119,6 @@ done: | |||
| 119 | return 0; | 119 | return 0; |
| 120 | } | 120 | } |
| 121 | 121 | ||
| 122 | unsigned int xprt_udp_slot_table_entries = RPC_DEF_SLOT_TABLE; | ||
| 123 | unsigned int xprt_tcp_slot_table_entries = RPC_DEF_SLOT_TABLE; | ||
| 124 | unsigned int xprt_min_resvport = RPC_DEF_MIN_RESVPORT; | ||
| 125 | EXPORT_SYMBOL(xprt_min_resvport); | ||
| 126 | unsigned int xprt_max_resvport = RPC_DEF_MAX_RESVPORT; | ||
| 127 | EXPORT_SYMBOL(xprt_max_resvport); | ||
| 128 | |||
| 129 | 122 | ||
| 130 | static unsigned int min_slot_table_size = RPC_MIN_SLOT_TABLE; | 123 | static unsigned int min_slot_table_size = RPC_MIN_SLOT_TABLE; |
| 131 | static unsigned int max_slot_table_size = RPC_MAX_SLOT_TABLE; | 124 | static unsigned int max_slot_table_size = RPC_MAX_SLOT_TABLE; |
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 2e1529217e65..0a51fd46a848 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
| @@ -36,6 +36,15 @@ | |||
| 36 | #include <net/tcp.h> | 36 | #include <net/tcp.h> |
| 37 | 37 | ||
| 38 | /* | 38 | /* |
| 39 | * xprtsock tunables | ||
| 40 | */ | ||
| 41 | unsigned int xprt_udp_slot_table_entries = RPC_DEF_SLOT_TABLE; | ||
| 42 | unsigned int xprt_tcp_slot_table_entries = RPC_DEF_SLOT_TABLE; | ||
| 43 | |||
| 44 | unsigned int xprt_min_resvport = RPC_DEF_MIN_RESVPORT; | ||
| 45 | unsigned int xprt_max_resvport = RPC_DEF_MAX_RESVPORT; | ||
| 46 | |||
| 47 | /* | ||
| 39 | * How many times to try sending a request on a socket before waiting | 48 | * How many times to try sending a request on a socket before waiting |
| 40 | * for the socket buffer to clear. | 49 | * for the socket buffer to clear. |
| 41 | */ | 50 | */ |
