コード例 #1
0
ファイル: actions.c プロジェクト: dventurino/ovs-rstp
static int push_mpls(struct sk_buff *skb, struct sw_flow_key *key,
                     const struct ovs_action_push_mpls *mpls)
{
    __be32 *new_mpls_lse;

    /* Networking stack do not allow simultaneous Tunnel and MPLS GSO. */
    if (skb->encapsulation)
        return -ENOTSUPP;

    if (skb_cow_head(skb, MPLS_HLEN) < 0)
        return -ENOMEM;

    skb_push(skb, MPLS_HLEN);
    memmove(skb_mac_header(skb) - MPLS_HLEN, skb_mac_header(skb),
            skb->mac_len);
    skb_reset_mac_header(skb);

    new_mpls_lse = (__be32 *)skb_mpls_header(skb);
    *new_mpls_lse = mpls->mpls_lse;

    skb_postpush_rcsum(skb, new_mpls_lse, MPLS_HLEN);

    update_ethertype(skb, eth_hdr(skb), mpls->mpls_ethertype);
    if (!ovs_skb_get_inner_protocol(skb))
        ovs_skb_set_inner_protocol(skb, skb->protocol);
    skb->protocol = mpls->mpls_ethertype;

    invalidate_flow_key(key);
    return 0;
}
コード例 #2
0
ファイル: actions.c プロジェクト: alexpilotti/ovs-test1
static int push_mpls(struct sk_buff *skb,
		     const struct ovs_action_push_mpls *mpls)
{
	__be32 *new_mpls_lse;
	struct ethhdr *hdr;

	if (skb_cow_head(skb, MPLS_HLEN) < 0)
		return -ENOMEM;

	skb_push(skb, MPLS_HLEN);
	memmove(skb_mac_header(skb) - MPLS_HLEN, skb_mac_header(skb),
		skb->mac_len);
	skb_reset_mac_header(skb);

	new_mpls_lse = (__be32 *)mac_header_end(skb);
	*new_mpls_lse = mpls->mpls_lse;

	if (skb->ip_summed == CHECKSUM_COMPLETE)
		skb->csum = csum_add(skb->csum, csum_partial(new_mpls_lse,
							     MPLS_HLEN, 0));

	hdr = eth_hdr(skb);
	hdr->h_proto = mpls->mpls_ethertype;
	if (!ovs_skb_get_inner_protocol(skb))
		ovs_skb_set_inner_protocol(skb, skb->protocol);
	skb->protocol = mpls->mpls_ethertype;
	return 0;
}
コード例 #3
0
ファイル: actions.c プロジェクト: rahul217/ovs
static int push_mpls(struct sk_buff *skb, struct sw_flow_key *key,
		     const struct ovs_action_push_mpls *mpls)
{
	__be32 *new_mpls_lse;
	struct ethhdr *hdr;

	/* Networking stack do not allow simultaneous Tunnel and MPLS GSO. */
	if (skb_encapsulation(skb))
		return -ENOTSUPP;

	if (skb_cow_head(skb, MPLS_HLEN) < 0)
		return -ENOMEM;

	skb_push(skb, MPLS_HLEN);
	memmove(skb_mac_header(skb) - MPLS_HLEN, skb_mac_header(skb),
		skb->mac_len);
	skb_reset_mac_header(skb);

	new_mpls_lse = (__be32 *)skb_mpls_header(skb);
	*new_mpls_lse = mpls->mpls_lse;

	if (skb->ip_summed == CHECKSUM_COMPLETE)
		skb->csum = csum_add(skb->csum, csum_partial(new_mpls_lse,
							     MPLS_HLEN, 0));

	hdr = eth_hdr(skb);
	hdr->h_proto = mpls->mpls_ethertype;
	if (!ovs_skb_get_inner_protocol(skb))
		ovs_skb_set_inner_protocol(skb, skb->protocol);
	skb->protocol = mpls->mpls_ethertype;

	invalidate_flow_key(key);
	return 0;
}
コード例 #4
0
ファイル: ip_tunnels_core.c プロジェクト: liusongpeng/ovs
bool ovs_skb_is_encapsulated(struct sk_buff *skb)
{
	/* checking for inner protocol should be sufficient on newer kernel, but
	 * old kernel just set encapsulation bit.
	 */
	return ovs_skb_get_inner_protocol(skb) || skb->encapsulation;
}
コード例 #5
0
ファイル: netdevice.c プロジェクト: Altiscale/ovs
struct sk_buff *rpl_skb_gso_segment(struct sk_buff *skb,
				    netdev_features_t features)
{
	int vlan_depth = ETH_HLEN;
	__be16 type = skb->protocol;
	__be16 skb_proto;
	struct sk_buff *skb_gso;

	while (type == htons(ETH_P_8021Q)) {
		struct vlan_hdr *vh;

		if (unlikely(!pskb_may_pull(skb, vlan_depth + VLAN_HLEN)))
			return ERR_PTR(-EINVAL);

		vh = (struct vlan_hdr *)(skb->data + vlan_depth);
		type = vh->h_vlan_encapsulated_proto;
		vlan_depth += VLAN_HLEN;
	}

	if (eth_p_mpls(type))
		type = ovs_skb_get_inner_protocol(skb);

	/* this hack needed to get regular skb_gso_segment() */
#undef skb_gso_segment
	skb_proto = skb->protocol;
	skb->protocol = type;

	skb_gso = skb_gso_segment(skb, features);
	skb->protocol = skb_proto;
	return skb_gso;
}
コード例 #6
0
ファイル: ip_tunnels_core.c プロジェクト: Altiscale/ovs
bool skb_is_encapsulated(struct sk_buff *skb)
{
	/* checking for inner protocol should be sufficient on newer kernel, but
	 * old kernel just set encapsulation bit.
	 */
	/* XXX: set inner protocol for all tunnel in OVS. */
	return ovs_skb_get_inner_protocol(skb) || skb_encapsulation(skb);
}
コード例 #7
0
ファイル: gso.c プロジェクト: ALutzG/ovs
static __be16 __skb_network_protocol(struct sk_buff *skb)
{
	__be16 type = skb->protocol;
	int vlan_depth = ETH_HLEN;

	while (type == htons(ETH_P_8021Q) || type == htons(ETH_P_8021AD)) {
		struct vlan_hdr *vh;

		if (unlikely(!pskb_may_pull(skb, vlan_depth + VLAN_HLEN)))
			return 0;

		vh = (struct vlan_hdr *)(skb->data + vlan_depth);
		type = vh->h_vlan_encapsulated_proto;
		vlan_depth += VLAN_HLEN;
	}

	if (eth_p_mpls(type))
		type = ovs_skb_get_inner_protocol(skb);

	return type;
}