From e28564c5fa42a009523c3e088a14c863bab5c691 Mon Sep 17 00:00:00 2001 From: Justin Pettit Date: Fri, 11 Apr 2008 17:40:05 -0700 Subject: [PATCH] Add support for OFPP_TABLE virtual port. --- datapath/datapath.c | 15 ++++++++++++++- datapath/forward.c | 19 +++++++++++++++---- datapath/forward.h | 4 ++++ include/openflow.h | 6 +++++- 4 files changed, 38 insertions(+), 6 deletions(-) diff --git a/datapath/datapath.c b/datapath/datapath.c index b80c7b20..0929b704 100644 --- a/datapath/datapath.c +++ b/datapath/datapath.c @@ -6,6 +6,7 @@ /* Functions for managing the dp interface/device. */ +#include #include #include #include @@ -465,7 +466,19 @@ int dp_output_port(struct datapath *dp, struct sk_buff *skb, int out_port) else if (out_port == OFPP_CONTROLLER) return dp_output_control(dp, skb, fwd_save_skb(skb), 0, OFPR_ACTION); - else if (out_port >= OFPP_MAX) + else if (out_port == OFPP_TABLE) { + struct sw_flow_key key; + struct sw_flow *flow; + + flow_extract(skb, skb->dev->br_port->port_no, &key); + flow = chain_lookup(dp->chain, &key); + if (likely(flow != NULL)) { + flow_used(flow, skb); + execute_actions(dp, skb, &key, flow->actions, flow->n_actions); + return 0; + } + return -ESRCH; + } else if (out_port >= OFPP_MAX) goto bad_port; p = dp->ports[out_port]; diff --git a/datapath/forward.c b/datapath/forward.c index a154393c..65a98aeb 100644 --- a/datapath/forward.c +++ b/datapath/forward.c @@ -21,9 +21,6 @@ /* FIXME: do we need to use GFP_ATOMIC everywhere here? */ -static void execute_actions(struct datapath *, struct sk_buff *, - const struct sw_flow_key *, - const struct ofp_action *, int n_actions); static int make_writable(struct sk_buff **); static struct sk_buff *retrieve_skb(uint32_t id); @@ -59,7 +56,7 @@ static int do_output(struct datapath *dp, struct sk_buff *skb, size_t max_len, max_len, OFPR_ACTION)); } -static void execute_actions(struct datapath *dp, struct sk_buff *skb, +void execute_actions(struct datapath *dp, struct sk_buff *skb, const struct sw_flow_key *key, const struct ofp_action *actions, int n_actions) { @@ -338,6 +335,7 @@ static int add_flow(struct sw_chain *chain, const struct ofp_flow_mod *ofm) { int error = -ENOMEM; + int i; int n_acts; struct sw_flow *flow; @@ -349,6 +347,19 @@ add_flow(struct sw_chain *chain, const struct ofp_flow_mod *ofm) goto error; } + /* To prevent loops, make sure there's no action to send to the + * OFP_TABLE virtual port. + */ + for (i=0; iactions[i]; + + if (a->type == htons(OFPAT_OUTPUT) + && a->arg.output.port == htons(OFPP_TABLE)) { + /* xxx Send fancy new error message? */ + goto error; + } + } + /* Allocate memory. */ flow = flow_alloc(n_acts, GFP_ATOMIC); if (flow == NULL) diff --git a/datapath/forward.h b/datapath/forward.h index 8e92330f..f061d2da 100644 --- a/datapath/forward.h +++ b/datapath/forward.h @@ -2,6 +2,7 @@ #define FORWARD_H 1 #include +#include "datapath.h" #include "flow.h" struct sk_buff; @@ -27,6 +28,9 @@ uint32_t fwd_save_skb(struct sk_buff *skb); void fwd_exit(void); +void execute_actions(struct datapath *, struct sk_buff *, + const struct sw_flow_key *, + const struct ofp_action *, int n_actions); struct sk_buff *execute_setter(struct sk_buff *, uint16_t, const struct sw_flow_key *, const struct ofp_action *); diff --git a/include/openflow.h b/include/openflow.h index 96a60c25..9c469066 100644 --- a/include/openflow.h +++ b/include/openflow.h @@ -61,7 +61,11 @@ enum ofp_port { OFPP_MAX = 0x100, /* Fake output "ports". */ - OFPP_NORMAL = 0xfffa, /* Process with normal L2/L3 switching */ + OFPP_TABLE = 0xfff9, /* Perform actions in flow table. + * NB: This can only be the destination + * port for packet-out messages. + */ + OFPP_NORMAL = 0xfffa, /* Process with normal L2/L3 switching. */ OFPP_FLOOD = 0xfffb, /* All physical ports except input port and those disabled by STP. */ OFPP_ALL = 0xfffc, /* All physical ports except input port. */ -- 2.30.2