[ovs-dev] [PATCH 2/2] tunneling: add the GRE set_tunnel_nw_dst action
romain.lenglet at berabera.info
romain.lenglet at berabera.info
Tue Oct 26 00:24:30 PDT 2010
From: Romain Lenglet <romain.lenglet at berabera.info>
This new action sets the destination IP address of the GRE packets for
a tunneled flow. If this action is not used, the address set for the
GRE port is used as a default value. This action must be used in
addition to an output action: first use set_tunnel_nw_dst to set the
destination address, then use output to output the flow into a GRE
vport. Header caching is automatically disabled for forwarding any
packet to which a set_tunnel_nw_dst action has been applied.
---
ChangeLog | 1 +
datapath/actions.c | 5 +++++
datapath/datapath.c | 1 +
datapath/datapath.h | 3 +++
datapath/tunnel.c | 22 ++++++++++++++--------
debian/changelog | 1 +
include/openflow/nicira-ext.h | 16 +++++++++++++++-
include/openvswitch/datapath-protocol.h | 12 +++++++-----
lib/odp-util.c | 4 ++++
lib/ofp-parse.c | 6 ++++++
lib/ofp-print.c | 8 ++++++++
lib/ofp-util.c | 1 +
ofproto/ofproto.c | 7 +++++++
13 files changed, 73 insertions(+), 14 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 527957a..89a5ab0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,7 @@ v1.1.0pre2 - 13 Sep 2010
------------------------
- Bug fixes
- Add option to disable GRE remote IP address matching
+ - Add action to set the GRE destination IP address per flow
v1.1.0pre1 - 31 Aug 2010
------------------------
diff --git a/datapath/actions.c b/datapath/actions.c
index 5904c83..20b88b2 100644
--- a/datapath/actions.c
+++ b/datapath/actions.c
@@ -438,6 +438,7 @@ int execute_actions(struct datapath *dp, struct sk_buff *skb,
}
OVS_CB(skb)->tun_id = 0;
+ OVS_CB(skb)->tun_nw_dst = 0;
for (; n_actions > 0; a++, n_actions--) {
if (prev_port != -1) {
@@ -462,6 +463,10 @@ int execute_actions(struct datapath *dp, struct sk_buff *skb,
OVS_CB(skb)->tun_id = a->tunnel.tun_id;
break;
+ case ODPAT_SET_TUNNEL_NW_DST:
+ OVS_CB(skb)->tun_nw_dst = a->nw_addr.nw_addr;
+ break;
+
case ODPAT_SET_DL_TCI:
skb = modify_vlan_tci(dp, skb, key, a, n_actions);
if (IS_ERR(skb))
diff --git a/datapath/datapath.c b/datapath/datapath.c
index 522d4ec..e46e5b5 100644
--- a/datapath/datapath.c
+++ b/datapath/datapath.c
@@ -891,6 +891,7 @@ static int validate_actions(const struct sw_flow_actions *actions)
case ODPAT_SET_TP_SRC:
case ODPAT_SET_TP_DST:
case ODPAT_SET_TUNNEL:
+ case ODPAT_SET_TUNNEL_NW_DST:
case ODPAT_SET_PRIORITY:
case ODPAT_POP_PRIORITY:
case ODPAT_DROP_SPOOFED_ARP:
diff --git a/datapath/datapath.h b/datapath/datapath.h
index 3a38235..804a203 100644
--- a/datapath/datapath.h
+++ b/datapath/datapath.h
@@ -140,12 +140,15 @@ enum csum_type {
* kernel versions.
* @tun_id: ID (in network byte order) of the tunnel that encapsulated this
* packet. It is 0 if the packet was not received on a tunnel.
+ * @tun_nw_dst: The remote IP address (in network byte order) of the tunnel.
+ * It is 0 if no remote IP address is defined.
*/
struct ovs_skb_cb {
struct dp_port *dp_port;
struct sw_flow *flow;
enum csum_type ip_summed;
__be32 tun_id;
+ __be32 tun_nw_dst;
};
#define OVS_CB(skb) ((struct ovs_skb_cb *)(skb)->cb)
diff --git a/datapath/tunnel.c b/datapath/tunnel.c
index 9c83a91..c6d0b1e 100644
--- a/datapath/tunnel.c
+++ b/datapath/tunnel.c
@@ -957,7 +957,8 @@ unlock:
static struct rtable *find_route(struct vport *vport,
const struct tnl_mutable_config *mutable,
- u8 tos, struct tnl_cache **cache)
+ u8 tos, struct tnl_cache **cache,
+ struct sk_buff *skb)
{
struct tnl_vport *tnl_vport = tnl_vport_priv(vport);
struct tnl_cache *cur_cache = rcu_dereference(tnl_vport->cache);
@@ -965,17 +966,22 @@ static struct rtable *find_route(struct vport *vport,
*cache = NULL;
tos = RT_TOS(tos);
- if (likely(tos == mutable->port_config.tos &&
+ if (!OVS_CB(skb)->tun_nw_dst &&
+ likely(tos == mutable->port_config.tos &&
check_cache_valid(cur_cache, mutable))) {
*cache = cur_cache;
return cur_cache->rt;
} else {
struct rtable *rt;
- struct flowi fl = { .nl_u = { .ip4_u =
- { .daddr = mutable->port_config.daddr,
- .saddr = mutable->port_config.saddr,
- .tos = tos } },
- .proto = tnl_vport->tnl_ops->ipproto };
+ struct flowi fl = {
+ .nl_u = {
+ .ip4_u = {
+ .daddr = OVS_CB(skb)->tun_nw_dst ?
+ OVS_CB(skb)->tun_nw_dst :
+ mutable->port_config.daddr,
+ .saddr = mutable->port_config.saddr,
+ .tos = tos } },
+ .proto = tnl_vport->tnl_ops->ipproto };
if (unlikely(ip_route_output_key(&init_net, &rt, &fl)))
return NULL;
@@ -1197,7 +1203,7 @@ int tnl_send(struct vport *vport, struct sk_buff *skb)
tos = INET_ECN_encapsulate(tos, inner_tos);
/* Route lookup */
- rt = find_route(vport, mutable, tos, &cache);
+ rt = find_route(vport, mutable, tos, &cache, skb);
if (unlikely(!rt))
goto error_free;
if (unlikely(!cache))
diff --git a/debian/changelog b/debian/changelog
index f427eb0..f36ff61 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -2,6 +2,7 @@ openvswitch (1.1.0pre2) unstable; urgency=low
* Bug fixes
* Add option to disable GRE remote IP address matching
+ * Add action to set the GRE destination IP address per flow
-- Open vSwitch team <dev at openvswitch.org> Mon, 13 Sep 2010 21:50:00 +0000
diff --git a/include/openflow/nicira-ext.h b/include/openflow/nicira-ext.h
index df2488b..f5a0142 100644
--- a/include/openflow/nicira-ext.h
+++ b/include/openflow/nicira-ext.h
@@ -152,7 +152,10 @@ enum nx_action_subtype {
/* Restore the queue to the value it was before any NXAST_SET_QUEUE
* actions were used. */
- NXAST_POP_QUEUE
+ NXAST_POP_QUEUE,
+
+ /* Set encapsulating tunnel remote IP address. */
+ NXAST_SET_TUNNEL_NW_DST
};
/* Action structure for NXAST_RESUBMIT. */
@@ -177,6 +180,17 @@ struct nx_action_set_tunnel {
};
OFP_ASSERT(sizeof(struct nx_action_set_tunnel) == 16);
+/* Action structure for NXAST_SET_TUNNEL_NW_DST. */
+struct nx_action_set_tunnel_nw_dst {
+ uint16_t type; /* OFPAT_VENDOR. */
+ uint16_t len; /* Length is 16. */
+ uint32_t vendor; /* NX_VENDOR_ID. */
+ uint16_t subtype; /* NXAST_SET_TUNNEL_NW_DST. */
+ uint8_t pad[2];
+ uint32_t nw_addr; /* Tunnel remote IP address. */
+};
+OFP_ASSERT(sizeof(struct nx_action_set_tunnel_nw_dst) == 16);
+
/* Action structure for NXAST_SET_QUEUE. */
struct nx_action_set_queue {
uint16_t type; /* OFPAT_VENDOR. */
diff --git a/include/openvswitch/datapath-protocol.h b/include/openvswitch/datapath-protocol.h
index b0e9dfb..ac3450b 100644
--- a/include/openvswitch/datapath-protocol.h
+++ b/include/openvswitch/datapath-protocol.h
@@ -268,10 +268,11 @@ struct odp_flowvec {
#define ODPAT_SET_TP_SRC 11 /* TCP/UDP source port. */
#define ODPAT_SET_TP_DST 12 /* TCP/UDP destination port. */
#define ODPAT_SET_TUNNEL 13 /* Set the encapsulating tunnel ID. */
-#define ODPAT_SET_PRIORITY 14 /* Set skb->priority. */
-#define ODPAT_POP_PRIORITY 15 /* Restore original skb->priority. */
-#define ODPAT_DROP_SPOOFED_ARP 16 /* Drop ARPs with spoofed source MAC. */
-#define ODPAT_N_ACTIONS 17
+#define ODPAT_SET_TUNNEL_NW_DST 14 /* Set the tunnel remote IP address. */
+#define ODPAT_SET_PRIORITY 15 /* Set skb->priority. */
+#define ODPAT_POP_PRIORITY 16 /* Restore original skb->priority. */
+#define ODPAT_DROP_SPOOFED_ARP 17 /* Drop ARPs with spoofed source MAC. */
+#define ODPAT_N_ACTIONS 18
struct odp_action_output {
uint16_t type; /* ODPAT_OUTPUT. */
@@ -305,7 +306,8 @@ struct odp_action_dl_addr {
uint8_t dl_addr[6]; /* Ethernet address. */
};
-/* Action structure for ODPAT_SET_NW_SRC/DST. */
+/* Action structure for ODPAT_SET_NW_SRC/DST and
+ ODPAT_SET_TUNNEL_NW_DST. */
struct odp_action_nw_addr {
uint16_t type; /* ODPAT_SET_TW_SRC/DST. */
uint16_t reserved;
diff --git a/lib/odp-util.c b/lib/odp-util.c
index 511ec3a..9b297d9 100644
--- a/lib/odp-util.c
+++ b/lib/odp-util.c
@@ -71,6 +71,10 @@ format_odp_action(struct ds *ds, const union odp_action *a)
case ODPAT_SET_TUNNEL:
ds_put_format(ds, "set_tunnel(0x%08"PRIx32")", ntohl(a->tunnel.tun_id));
break;
+ case ODPAT_SET_TUNNEL_NW_DST:
+ ds_put_format(ds, "set_tunnel_nw_dst("IP_FMT")",
+ IP_ARGS(&a->nw_addr.nw_addr));
+ break;
case ODPAT_SET_DL_TCI:
ds_put_format(ds, "set_tci(vid=%"PRIu16",pcp=%d)",
vlan_tci_to_vid(a->dl_tci.tci),
diff --git a/lib/ofp-parse.c b/lib/ofp-parse.c
index e6af036..192f80f 100644
--- a/lib/ofp-parse.c
+++ b/lib/ofp-parse.c
@@ -266,6 +266,12 @@ str_to_action(char *str, struct ofpbuf *b)
nast->vendor = htonl(NX_VENDOR_ID);
nast->subtype = htons(NXAST_SET_TUNNEL);
nast->tun_id = htonl(str_to_u32(arg));
+ } else if (!strcasecmp(act, "set_tunnel_nw_dst")) {
+ struct nx_action_set_tunnel_nw_dst *nastnd;
+ nastnd = put_action(b, sizeof *nastnd, OFPAT_VENDOR);
+ nastnd->vendor = htonl(NX_VENDOR_ID);
+ nastnd->subtype = htons(NXAST_SET_TUNNEL_NW_DST);
+ str_to_ip(arg, &nastnd->nw_addr);
} else if (!strcasecmp(act, "drop_spoofed_arp")) {
struct nx_action_header *nah;
nah = put_action(b, sizeof *nah, OFPAT_VENDOR);
diff --git a/lib/ofp-print.c b/lib/ofp-print.c
index 2591484..074d979 100644
--- a/lib/ofp-print.c
+++ b/lib/ofp-print.c
@@ -201,6 +201,14 @@ ofp_print_nx_action(struct ds *string, const struct nx_action_header *nah)
break;
}
+ case NXAST_SET_TUNNEL_NW_DST: {
+ const struct nx_action_set_tunnel_nw_dst *nastnd =
+ (struct nx_action_set_tunnel_nw_dst *)nah;
+ ds_put_format(string, "set_tunnel_nw_dst:"IP_FMT,
+ IP_ARGS(&nastnd->nw_addr));
+ break;
+ }
+
case NXAST_DROP_SPOOFED_ARP:
ds_put_cstr(string, "drop_spoofed_arp");
break;
diff --git a/lib/ofp-util.c b/lib/ofp-util.c
index 99e5943..cf95b47 100644
--- a/lib/ofp-util.c
+++ b/lib/ofp-util.c
@@ -564,6 +564,7 @@ check_nicira_action(const union ofp_action *a, unsigned int len)
switch (ntohs(nah->subtype)) {
case NXAST_RESUBMIT:
case NXAST_SET_TUNNEL:
+ case NXAST_SET_TUNNEL_NW_DST:
case NXAST_DROP_SPOOFED_ARP:
case NXAST_SET_QUEUE:
case NXAST_POP_QUEUE:
diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
index ab5d476..1e2cc61 100644
--- a/ofproto/ofproto.c
+++ b/ofproto/ofproto.c
@@ -2700,6 +2700,7 @@ xlate_nicira_action(struct action_xlate_ctx *ctx,
{
const struct nx_action_resubmit *nar;
const struct nx_action_set_tunnel *nast;
+ const struct nx_action_set_tunnel_nw_dst *nastnd;
const struct nx_action_set_queue *nasq;
union odp_action *oa;
int subtype = ntohs(nah->subtype);
@@ -2717,6 +2718,12 @@ xlate_nicira_action(struct action_xlate_ctx *ctx,
ctx->flow.tun_id = oa->tunnel.tun_id = nast->tun_id;
break;
+ case NXAST_SET_TUNNEL_NW_DST:
+ nastnd = (const struct nx_action_set_tunnel_nw_dst *) nah;
+ oa = odp_actions_add(ctx->out, ODPAT_SET_TUNNEL_NW_DST);
+ oa->nw_addr.nw_addr = nastnd->nw_addr;
+ break;
+
case NXAST_DROP_SPOOFED_ARP:
if (ctx->flow.dl_type == htons(ETH_TYPE_ARP)) {
odp_actions_add(ctx->out, ODPAT_DROP_SPOOFED_ARP);
--
1.7.2.3
More information about the dev
mailing list