示例#1
0
static unsigned int br_nf_forward_arp(void *priv,
				      struct sk_buff *skb,
				      const struct nf_hook_state *state)
{
	struct net_bridge_port *p;
	struct net_bridge *br;
	struct net_device **d = (struct net_device **)(skb->cb);

	p = br_port_get_rcu(state->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 = state->in;
	NF_HOOK(NFPROTO_ARP, NF_ARP_FORWARD, state->net, state->sk, skb,
		state->in, state->out, br_nf_forward_finish);

	return NF_STOLEN;
}
示例#2
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);

	br_nf_hook_thresh(NF_BR_FORWARD, net, sk, skb, in, skb->dev,
			  br_forward_finish);
	return 0;
}
示例#3
0
/* PF_BRIDGE/FORWARD *************************************************/
static int br_nf_forward_finish(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)) {
        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->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, sk, skb,
                   in, skb->dev, br_forward_finish, 1);
    return 0;
}
示例#4
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)) {
    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;
}
示例#5
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;
}