Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'nf' of git://1984.lsi.us.es/net

+51 -38
+2 -2
include/linux/netfilter_bridge/ebtables.h
··· 285 285 struct module *me; 286 286 }; 287 287 288 - #define EBT_ALIGN(s) (((s) + (__alignof__(struct ebt_replace)-1)) & \ 289 - ~(__alignof__(struct ebt_replace)-1)) 288 + #define EBT_ALIGN(s) (((s) + (__alignof__(struct _xt_align)-1)) & \ 289 + ~(__alignof__(struct _xt_align)-1)) 290 290 extern struct ebt_table *ebt_register_table(struct net *net, 291 291 const struct ebt_table *table); 292 292 extern void ebt_unregister_table(struct net *net, struct ebt_table *table);
+1 -1
net/netfilter/ipvs/ip_vs_core.c
··· 232 232 __be16 dport = 0; /* destination port to forward */ 233 233 unsigned int flags; 234 234 struct ip_vs_conn_param param; 235 + const union nf_inet_addr fwmark = { .ip = htonl(svc->fwmark) }; 235 236 union nf_inet_addr snet; /* source network of the client, 236 237 after masking */ 237 238 ··· 268 267 { 269 268 int protocol = iph.protocol; 270 269 const union nf_inet_addr *vaddr = &iph.daddr; 271 - const union nf_inet_addr fwmark = { .ip = htonl(svc->fwmark) }; 272 270 __be16 vport = 0; 273 271 274 272 if (dst_port == svc->port) {
+16 -27
net/netfilter/nf_conntrack_netlink.c
··· 1367 1367 nf_ct_protonum(ct)); 1368 1368 if (helper == NULL) { 1369 1369 rcu_read_unlock(); 1370 - spin_unlock_bh(&nf_conntrack_lock); 1371 1370 #ifdef CONFIG_MODULES 1372 1371 if (request_module("nfct-helper-%s", helpname) < 0) { 1373 - spin_lock_bh(&nf_conntrack_lock); 1374 1372 err = -EOPNOTSUPP; 1375 1373 goto err1; 1376 1374 } 1377 1375 1378 - spin_lock_bh(&nf_conntrack_lock); 1379 1376 rcu_read_lock(); 1380 1377 helper = __nf_conntrack_helper_find(helpname, 1381 1378 nf_ct_l3num(ct), ··· 1466 1469 tstamp->start = ktime_to_ns(ktime_get_real()); 1467 1470 1468 1471 add_timer(&ct->timeout); 1472 + spin_lock_bh(&nf_conntrack_lock); 1469 1473 nf_conntrack_hash_insert(ct); 1474 + nf_conntrack_get(&ct->ct_general); 1475 + spin_unlock_bh(&nf_conntrack_lock); 1470 1476 rcu_read_unlock(); 1471 1477 1472 1478 return ct; ··· 1490 1490 struct nf_conntrack_tuple otuple, rtuple; 1491 1491 struct nf_conntrack_tuple_hash *h = NULL; 1492 1492 struct nfgenmsg *nfmsg = nlmsg_data(nlh); 1493 + struct nf_conn *ct; 1493 1494 u_int8_t u3 = nfmsg->nfgen_family; 1494 1495 u16 zone; 1495 1496 int err; ··· 1513 1512 1514 1513 spin_lock_bh(&nf_conntrack_lock); 1515 1514 if (cda[CTA_TUPLE_ORIG]) 1516 - h = __nf_conntrack_find(net, zone, &otuple); 1515 + h = nf_conntrack_find_get(net, zone, &otuple); 1517 1516 else if (cda[CTA_TUPLE_REPLY]) 1518 - h = __nf_conntrack_find(net, zone, &rtuple); 1517 + h = nf_conntrack_find_get(net, zone, &rtuple); 1518 + spin_unlock_bh(&nf_conntrack_lock); 1519 1519 1520 1520 if (h == NULL) { 1521 1521 err = -ENOENT; 1522 1522 if (nlh->nlmsg_flags & NLM_F_CREATE) { 1523 - struct nf_conn *ct; 1524 1523 enum ip_conntrack_events events; 1525 1524 1526 1525 ct = ctnetlink_create_conntrack(net, zone, cda, &otuple, 1527 1526 &rtuple, u3); 1528 - if (IS_ERR(ct)) { 1529 - err = PTR_ERR(ct); 1530 - goto out_unlock; 1531 - } 1527 + if (IS_ERR(ct)) 1528 + return PTR_ERR(ct); 1529 + 1532 1530 err = 0; 1533 - nf_conntrack_get(&ct->ct_general); 1534 - spin_unlock_bh(&nf_conntrack_lock); 1535 1531 if (test_bit(IPS_EXPECTED_BIT, &ct->status)) 1536 1532 events = IPCT_RELATED; 1537 1533 else ··· 1543 1545 ct, NETLINK_CB(skb).pid, 1544 1546 nlmsg_report(nlh)); 1545 1547 nf_ct_put(ct); 1546 - } else 1547 - spin_unlock_bh(&nf_conntrack_lock); 1548 + } 1548 1549 1549 1550 return err; 1550 1551 } 1551 1552 /* implicit 'else' */ 1552 1553 1553 - /* We manipulate the conntrack inside the global conntrack table lock, 1554 - * so there's no need to increase the refcount */ 1555 1554 err = -EEXIST; 1555 + ct = nf_ct_tuplehash_to_ctrack(h); 1556 1556 if (!(nlh->nlmsg_flags & NLM_F_EXCL)) { 1557 - struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(h); 1558 - 1557 + spin_lock_bh(&nf_conntrack_lock); 1559 1558 err = ctnetlink_change_conntrack(ct, cda); 1559 + spin_unlock_bh(&nf_conntrack_lock); 1560 1560 if (err == 0) { 1561 - nf_conntrack_get(&ct->ct_general); 1562 - spin_unlock_bh(&nf_conntrack_lock); 1563 1561 nf_conntrack_eventmask_report((1 << IPCT_REPLY) | 1564 1562 (1 << IPCT_ASSURED) | 1565 1563 (1 << IPCT_HELPER) | ··· 1564 1570 (1 << IPCT_MARK), 1565 1571 ct, NETLINK_CB(skb).pid, 1566 1572 nlmsg_report(nlh)); 1567 - nf_ct_put(ct); 1568 - } else 1569 - spin_unlock_bh(&nf_conntrack_lock); 1570 - 1571 - return err; 1573 + } 1572 1574 } 1573 1575 1574 - out_unlock: 1575 - spin_unlock_bh(&nf_conntrack_lock); 1576 + nf_ct_put(ct); 1576 1577 return err; 1577 1578 } 1578 1579
+32 -8
net/netfilter/nf_queue.c
··· 203 203 return status; 204 204 } 205 205 206 + #ifdef CONFIG_BRIDGE_NETFILTER 207 + /* When called from bridge netfilter, skb->data must point to MAC header 208 + * before calling skb_gso_segment(). Else, original MAC header is lost 209 + * and segmented skbs will be sent to wrong destination. 210 + */ 211 + static void nf_bridge_adjust_skb_data(struct sk_buff *skb) 212 + { 213 + if (skb->nf_bridge) 214 + __skb_push(skb, skb->network_header - skb->mac_header); 215 + } 216 + 217 + static void nf_bridge_adjust_segmented_data(struct sk_buff *skb) 218 + { 219 + if (skb->nf_bridge) 220 + __skb_pull(skb, skb->network_header - skb->mac_header); 221 + } 222 + #else 223 + #define nf_bridge_adjust_skb_data(s) do {} while (0) 224 + #define nf_bridge_adjust_segmented_data(s) do {} while (0) 225 + #endif 226 + 206 227 int nf_queue(struct sk_buff *skb, 207 228 struct list_head *elem, 208 229 u_int8_t pf, unsigned int hook, ··· 233 212 unsigned int queuenum) 234 213 { 235 214 struct sk_buff *segs; 236 - int err; 215 + int err = -EINVAL; 237 216 unsigned int queued; 238 217 239 218 if (!skb_is_gso(skb)) ··· 249 228 break; 250 229 } 251 230 231 + nf_bridge_adjust_skb_data(skb); 252 232 segs = skb_gso_segment(skb, 0); 253 233 /* Does not use PTR_ERR to limit the number of error codes that can be 254 234 * returned by nf_queue. For instance, callers rely on -ECANCELED to mean 255 235 * 'ignore this hook'. 256 236 */ 257 237 if (IS_ERR(segs)) 258 - return -EINVAL; 259 - 238 + goto out_err; 260 239 queued = 0; 261 240 err = 0; 262 241 do { 263 242 struct sk_buff *nskb = segs->next; 264 243 265 244 segs->next = NULL; 266 - if (err == 0) 245 + if (err == 0) { 246 + nf_bridge_adjust_segmented_data(segs); 267 247 err = __nf_queue(segs, elem, pf, hook, indev, 268 248 outdev, okfn, queuenum); 249 + } 269 250 if (err == 0) 270 251 queued++; 271 252 else ··· 275 252 segs = nskb; 276 253 } while (segs); 277 254 278 - /* also free orig skb if only some segments were queued */ 279 - if (unlikely(err && queued)) 280 - err = 0; 281 - if (err == 0) 255 + if (queued) { 282 256 kfree_skb(skb); 257 + return 0; 258 + } 259 + out_err: 260 + nf_bridge_adjust_segmented_data(skb); 283 261 return err; 284 262 } 285 263