Beispiel #1
0
/* PF_BRIDGE/FORWARD *************************************************/
static int br_nf_forward_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
{
	struct nf_bridge_info *nf_bridge = nf_bridge_info_get(skb);
	struct net_device *in;

	if (!IS_ARP(skb) && !IS_VLAN_ARP(skb)) {

		if (skb->protocol == htons(ETH_P_IP))
			nf_bridge->frag_max_size = IPCB(skb)->frag_max_size;

		if (skb->protocol == htons(ETH_P_IPV6))
			nf_bridge->frag_max_size = IP6CB(skb)->frag_max_size;

		in = nf_bridge->physindev;
		if (nf_bridge->pkt_otherhost) {
			skb->pkt_type = PACKET_OTHERHOST;
			nf_bridge->pkt_otherhost = false;
		}
		nf_bridge_update_protocol(skb);
	} else {
		in = *((struct net_device **)(skb->cb));
	}
	nf_bridge_push_encap_header(skb);

	NF_HOOK_THRESH(NFPROTO_BRIDGE, NF_BR_FORWARD, net, sk, skb,
		       in, skb->dev, br_forward_finish, 1);
	return 0;
}
Beispiel #2
0
/* PF_BRIDGE/FORWARD *************************************************/
static int br_nf_forward_finish(struct sk_buff *skb)
{
	struct nf_bridge_info *nf_bridge = skb->nf_bridge;
	struct net_device *in;

	if (!IS_ARP(skb) && !IS_VLAN_ARP(skb)) {
		int frag_max_size;

		if (skb->protocol == htons(ETH_P_IP)) {
			frag_max_size = IPCB(skb)->frag_max_size;
			BR_INPUT_SKB_CB(skb)->frag_max_size = frag_max_size;
		}

		in = nf_bridge->physindev;
		if (nf_bridge->mask & BRNF_PKT_TYPE) {
			skb->pkt_type = PACKET_OTHERHOST;
			nf_bridge->mask ^= BRNF_PKT_TYPE;
		}
		nf_bridge_update_protocol(skb);
	} else {
		in = *((struct net_device **)(skb->cb));
	}
	nf_bridge_push_encap_header(skb);

	NF_HOOK_THRESH(NFPROTO_BRIDGE, NF_BR_FORWARD, skb, in,
		       skb->dev, br_forward_finish, 1);
	return 0;
}
Beispiel #3
0
static unsigned int br_nf_forward_arp(unsigned int hook, struct sk_buff *skb,
                                      const struct net_device *in,
                                      const struct net_device *out,
                                      int (*okfn)(struct sk_buff *)) {
  struct net_bridge_port *p;
  struct net_bridge *br;
  struct net_device **d = (struct net_device **)(skb->cb);

  p = br_port_get_rcu(out);
  if (p == NULL) {
    return NF_ACCEPT;
  }
  br = p->br;

  if (!brnf_call_arptables && !br->nf_call_arptables) {
    return NF_ACCEPT;
  }

  if (!IS_ARP(skb)) {
    if (!IS_VLAN_ARP(skb)) {
      return NF_ACCEPT;
    }
    nf_bridge_pull_encap_header(skb);
  }

  if (arp_hdr(skb)->ar_pln != 4) {
    if (IS_VLAN_ARP(skb)) {
      nf_bridge_push_encap_header(skb);
    }
    return NF_ACCEPT;
  }
  *d = (struct net_device *)in;
  NF_HOOK(NFPROTO_ARP, NF_ARP_FORWARD, skb, (struct net_device *)in,
          (struct net_device *)out, br_nf_forward_finish);

  return NF_STOLEN;
}