#include "flow.h"
#include <inttypes.h>
#include <netinet/in.h>
+#include <stdlib.h>
#include <string.h>
#include "hash.h"
#include "ofpbuf.h"
memset(flow, 0, sizeof *flow);
flow->dl_vlan = htons(OFP_VLAN_NONE);
- flow->in_port = htons(in_port);
+ flow->in_port = in_port;
packet->l2 = b.data;
packet->l3 = NULL;
}
void
-flow_fill_match(struct ofp_match *to, const struct flow *from,
- uint32_t wildcards)
+flow_to_match(const struct flow *flow, uint32_t wildcards, struct ofp_match *match)
{
- to->wildcards = htonl(wildcards);
- to->in_port = from->in_port;
- to->dl_vlan = from->dl_vlan;
- memcpy(to->dl_src, from->dl_src, ETH_ADDR_LEN);
- memcpy(to->dl_dst, from->dl_dst, ETH_ADDR_LEN);
- to->dl_type = from->dl_type;
- to->nw_src = from->nw_src;
- to->nw_dst = from->nw_dst;
- to->nw_proto = from->nw_proto;
- to->tp_src = from->tp_src;
- to->tp_dst = from->tp_dst;
- to->pad = 0;
+ match->wildcards = htonl(wildcards);
+ match->in_port = htons(flow->in_port);
+ match->dl_vlan = flow->dl_vlan;
+ memcpy(match->dl_src, flow->dl_src, ETH_ADDR_LEN);
+ memcpy(match->dl_dst, flow->dl_dst, ETH_ADDR_LEN);
+ match->dl_type = flow->dl_type;
+ match->nw_src = flow->nw_src;
+ match->nw_dst = flow->nw_dst;
+ match->nw_proto = flow->nw_proto;
+ match->tp_src = flow->tp_src;
+ match->tp_dst = flow->tp_dst;
+ match->pad = 0;
+}
+
+void
+flow_from_match(struct flow *flow, uint32_t *wildcards,
+ const struct ofp_match *match)
+{
+ if (wildcards) {
+ *wildcards = ntohl(match->wildcards);
+ }
+ flow->nw_src = match->nw_src;
+ flow->nw_dst = match->nw_dst;
+ flow->in_port = ntohs(match->in_port);
+ flow->dl_vlan = match->dl_vlan;
+ flow->dl_type = match->dl_type;
+ flow->tp_src = match->tp_src;
+ flow->tp_dst = match->tp_dst;
+ memcpy(flow->dl_src, match->dl_src, ETH_ADDR_LEN);
+ memcpy(flow->dl_dst, match->dl_dst, ETH_ADDR_LEN);
+ flow->nw_proto = match->nw_proto;
+ flow->reserved = 0;
+}
+
+char *
+flow_to_string(const struct flow *flow)
+{
+ return xasprintf("port%04x:vlan%d mac"ETH_ADDR_FMT"->"ETH_ADDR_FMT" "
+ "type%04x proto%"PRId8" ip"IP_FMT"->"IP_FMT" port%d->%d",
+ flow->in_port, ntohs(flow->dl_vlan),
+ ETH_ADDR_ARGS(flow->dl_src), ETH_ADDR_ARGS(flow->dl_dst),
+ ntohs(flow->dl_type), flow->nw_proto,
+ IP_ARGS(&flow->nw_src), IP_ARGS(&flow->nw_dst),
+ ntohs(flow->tp_src), ntohs(flow->tp_dst));
}
void
flow_print(FILE *stream, const struct flow *flow)
{
- fprintf(stream,
- "port%04x:vlan%d mac"ETH_ADDR_FMT"->"ETH_ADDR_FMT" "
- "type%04x proto%"PRId8" ip"IP_FMT"->"IP_FMT" port%d->%d",
- ntohs(flow->in_port), ntohs(flow->dl_vlan),
- ETH_ADDR_ARGS(flow->dl_src), ETH_ADDR_ARGS(flow->dl_dst),
- ntohs(flow->dl_type), flow->nw_proto,
- IP_ARGS(&flow->nw_src), IP_ARGS(&flow->nw_dst),
- ntohs(flow->tp_src), ntohs(flow->tp_dst));
+ char *s = flow_to_string(flow);
+ fputs(s, stream);
+ free(s);
}
BUILD_ASSERT_DECL(sizeof(struct flow) == 32);
int flow_extract(struct ofpbuf *, uint16_t in_port, struct flow *);
-void flow_fill_match(struct ofp_match *, const struct flow *,
- uint32_t wildcards);
+void flow_to_match(const struct flow *, uint32_t wildcards,
+ struct ofp_match *);
+void flow_from_match(struct flow *, uint32_t *wildcards,
+ const struct ofp_match *);
+char *flow_to_string(const struct flow *);
void flow_print(FILE *, const struct flow *);
static inline int flow_compare(const struct flow *, const struct flow *);
static inline bool flow_equal(const struct flow *, const struct flow *);
static packet_handler_func process_features_reply;
static packet_handler_func process_port_status;
-static void flow_from_match(struct flow *, const struct ofp_match *);
-
static void
bridge_process_msg(struct bridge *br, struct ofpbuf *msg)
{
/* We don't use flows with wildcards, so there's nothing to do. */
return;
}
- flow_from_match(&flow, &ofe->match);
+ flow_from_match(&flow, NULL, &ofe->match);
f = ft_lookup(br->ft, &flow, flow_hash(&flow, 0));
if (f) {
}
phy_port_changed(br, ops->reason, &ops->desc);
}
-
-static void
-flow_from_match(struct flow *flow, const struct ofp_match *match)
-{
- flow->nw_src = match->nw_src;
- flow->nw_dst = match->nw_dst;
- flow->in_port = match->in_port;
- flow->dl_vlan = match->dl_vlan;
- flow->dl_type = match->dl_type;
- flow->tp_src = match->tp_src;
- flow->tp_dst = match->tp_dst;
- memcpy(flow->dl_src, match->dl_src, ETH_ADDR_LEN);
- memcpy(flow->dl_dst, match->dl_dst, ETH_ADDR_LEN);
- flow->nw_proto = match->nw_proto;
- flow->reserved = 0;
-}
\f
/* Flow statistics collection. */
/* XXX delete flow */
continue;
}
- flow_from_match(&flow, &fs->match);
+ flow_from_match(&flow, NULL, &fs->match);
hash = flow_hash(&flow, 0);
f = ft_lookup(br->ft, &flow, hash);