diff mbox

[4/4] gre: Add Transparent Ethernet Bridging

Message ID 48EDC429.5090502@snapgear.com
State RFC, archived
Delegated to: David Miller
Headers show

Commit Message

Philip Craig Oct. 9, 2008, 8:43 a.m. UTC
Thanks for doing this work, much appreciated.

I haven't tested your patches yet, but when I was attempting this,
I needed the attached patch to get it to work with bridging and
netfilter, otherwise gre tries to call
skb->dst->ops->update_pmtu(skb->dst, mtu);


Herbert Xu wrote:
> @@ -530,7 +572,13 @@ static int ipgre_rcv(struct sk_buff *skb)
>  		dst_release(skb->dst);
>  		skb->dst = NULL;
>  		nf_reset(skb);
> +
> +		if (tunnel->dev->type == ARPHRD_ETHER)
> +			skb->protocol = eth_type_trans(skb, skb->dev);

Do you need to check pskb_may_pull(skb, ETH_HLEN)?

> +
> +		skb_reset_network_header(skb);
>  		ipgre_ecn_decapsulate(iph, skb);
> +
>  		netif_rx(skb);
>  		read_unlock(&ipgre_lock);
>  		return(0);

Comments

Herbert Xu Oct. 9, 2008, 10:39 a.m. UTC | #1
On Thu, Oct 09, 2008 at 06:43:21PM +1000, Philip Craig wrote:
>
> Herbert Xu wrote:
> > @@ -530,7 +572,13 @@ static int ipgre_rcv(struct sk_buff *skb)
> >  		dst_release(skb->dst);
> >  		skb->dst = NULL;
> >  		nf_reset(skb);
> > +
> > +		if (tunnel->dev->type == ARPHRD_ETHER)
> > +			skb->protocol = eth_type_trans(skb, skb->dev);
> 
> Do you need to check pskb_may_pull(skb, ETH_HLEN)?

Good point, I'll fix this up.

> +/*
> + * We've finished passing through netfilter, so we can remove the fake dst.
> + * This is required by some lower layers, eg ip_gre
> + */
> +static int br_nf_dev_queue_xmit_finish(struct sk_buff *skb)
> +{
> +	if (skb->dst == (struct dst_entry *)&__fake_rtable) {
> +		dst_release(skb->dst);
> +		skb->dst = NULL;
> +	}
> +
> +	return br_dev_queue_push_xmit(skb);
> +}

Alternatively we could give fake_rtable an ops structure.

Thanks,
diff mbox

Patch

--- linux-2.6.x/net/bridge/br_netfilter.c	18 Jun 2006 23:30:55 -0000	1.1.1.25
+++ linux-2.6.x/net/bridge/br_netfilter.c	11 Aug 2006 04:10:04 -0000
@@ -765,14 +765,28 @@  out:
 	return NF_STOLEN;
 }
 
+/*
+ * We've finished passing through netfilter, so we can remove the fake dst.
+ * This is required by some lower layers, eg ip_gre
+ */
+static int br_nf_dev_queue_xmit_finish(struct sk_buff *skb)
+{
+	if (skb->dst == (struct dst_entry *)&__fake_rtable) {
+		dst_release(skb->dst);
+		skb->dst = NULL;
+	}
+
+	return br_dev_queue_push_xmit(skb);
+}
+
 static int br_nf_dev_queue_xmit(struct sk_buff *skb)
 {
 	if (skb->protocol == htons(ETH_P_IP) &&
 	    skb->len > skb->dev->mtu &&
 	    !(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size))
-		return ip_fragment(skb, br_dev_queue_push_xmit);
+		return ip_fragment(skb, br_nf_dev_queue_xmit_finish);
 	else
-		return br_dev_queue_push_xmit(skb);
+		return br_nf_dev_queue_xmit_finish(skb);
 }
 
 /* PF_BRIDGE/POST_ROUTING ********************************************/