aboutsummaryrefslogtreecommitdiff
path: root/lib/dpif-linux.c
diff options
context:
space:
mode:
authorBen Pfaff <blp@nicira.com>2011-10-19 21:33:44 -0700
committerBen Pfaff <blp@nicira.com>2011-10-21 15:07:36 -0700
commit7257b535ab8e5fafd811c5f6788205eefdd44948 (patch)
tree75072ea003837f756ce6910fb5e0ba3113db30be /lib/dpif-linux.c
parent4edb9ae90e4092f5f56b9d914d2b88783c49860d (diff)
Implement new fragment handling policy.
Until now, OVS has handled IP fragments more awkwardly than necessary. It has not been possible to match on L4 headers, even in fragments with offset 0 where they are actually present. This means that there was no way to implement ACLs that treat, say, different TCP ports differently, on fragmented traffic; instead, all decisions for fragment forwarding had to be made on the basis of L2 and L3 headers alone. This commit improves the situation significantly. It is still not possible to match on L4 headers in fragments with nonzero offset, because that information is simply not present in such fragments, but this commit adds the ability to match on L4 headers for fragments with zero offset. This means that it becomes possible to implement ACLs that drop such "first fragments" on the basis of L4 headers. In practice, that effectively blocks even fragmented traffic on an L4 basis, because the receiving IP stack cannot reassemble a full packet when the first fragment is missing. This commit works by adding a new "fragment type" to the kernel flow match and making it available through OpenFlow as a new NXM field named NXM_NX_IP_FRAG. Because OpenFlow 1.0 explicitly says that the L4 fields are always 0 for IP fragments, it adds a new OpenFlow fragment handling mode that fills in the L4 fields for "first fragments". It also enhances ovs-ofctl to allow users to configure this new fragment handling mode and to parse the new field. Signed-off-by: Ben Pfaff <blp@nicira.com> Bug #7557.
Diffstat (limited to 'lib/dpif-linux.c')
-rw-r--r--lib/dpif-linux.c40
1 files changed, 0 insertions, 40 deletions
diff --git a/lib/dpif-linux.c b/lib/dpif-linux.c
index fa6a05e0..2466f915 100644
--- a/lib/dpif-linux.c
+++ b/lib/dpif-linux.c
@@ -79,7 +79,6 @@ struct dpif_linux_dp {
const char *name; /* OVS_DP_ATTR_NAME. */
const uint32_t *upcall_pid; /* OVS_DP_UPCALL_PID. */
struct ovs_dp_stats stats; /* OVS_DP_ATTR_STATS. */
- enum ovs_datapath_frag ipv4_frags; /* OVS_DP_ATTR_IPV4_FRAGS. */
};
static void dpif_linux_dp_init(struct dpif_linux_dp *);
@@ -347,7 +346,6 @@ dpif_linux_get_stats(const struct dpif *dpif_, struct dpif_dp_stats *stats)
error = dpif_linux_dp_get(dpif_, &dp, &buf);
if (!error) {
- stats->n_frags = dp.stats.n_frags;
stats->n_hit = dp.stats.n_hit;
stats->n_missed = dp.stats.n_missed;
stats->n_lost = dp.stats.n_lost;
@@ -358,34 +356,6 @@ dpif_linux_get_stats(const struct dpif *dpif_, struct dpif_dp_stats *stats)
}
static int
-dpif_linux_get_drop_frags(const struct dpif *dpif_, bool *drop_fragsp)
-{
- struct dpif_linux_dp dp;
- struct ofpbuf *buf;
- int error;
-
- error = dpif_linux_dp_get(dpif_, &dp, &buf);
- if (!error) {
- *drop_fragsp = dp.ipv4_frags == OVS_DP_FRAG_DROP;
- ofpbuf_delete(buf);
- }
- return error;
-}
-
-static int
-dpif_linux_set_drop_frags(struct dpif *dpif_, bool drop_frags)
-{
- struct dpif_linux *dpif = dpif_linux_cast(dpif_);
- struct dpif_linux_dp dp;
-
- dpif_linux_dp_init(&dp);
- dp.cmd = OVS_DP_CMD_SET;
- dp.dp_ifindex = dpif->dp_ifindex;
- dp.ipv4_frags = drop_frags ? OVS_DP_FRAG_DROP : OVS_DP_FRAG_ZERO;
- return dpif_linux_dp_transact(&dp, NULL, NULL);
-}
-
-static int
dpif_linux_port_add(struct dpif *dpif_, struct netdev *netdev,
uint16_t *port_nop)
{
@@ -1206,8 +1176,6 @@ const struct dpif_class dpif_linux_class = {
dpif_linux_run,
dpif_linux_wait,
dpif_linux_get_stats,
- dpif_linux_get_drop_frags,
- dpif_linux_set_drop_frags,
dpif_linux_port_add,
dpif_linux_port_del,
dpif_linux_port_query_by_number,
@@ -1540,7 +1508,6 @@ dpif_linux_dp_from_ofpbuf(struct dpif_linux_dp *dp, const struct ofpbuf *buf)
.min_len = sizeof(struct ovs_dp_stats),
.max_len = sizeof(struct ovs_dp_stats),
.optional = true },
- [OVS_DP_ATTR_IPV4_FRAGS] = { .type = NL_A_U32, .optional = true },
};
struct nlattr *a[ARRAY_SIZE(ovs_datapath_policy)];
@@ -1571,9 +1538,6 @@ dpif_linux_dp_from_ofpbuf(struct dpif_linux_dp *dp, const struct ofpbuf *buf)
memcpy(&dp->stats, nl_attr_get(a[OVS_DP_ATTR_STATS]),
sizeof dp->stats);
}
- if (a[OVS_DP_ATTR_IPV4_FRAGS]) {
- dp->ipv4_frags = nl_attr_get_u32(a[OVS_DP_ATTR_IPV4_FRAGS]);
- }
return 0;
}
@@ -1599,10 +1563,6 @@ dpif_linux_dp_to_ofpbuf(const struct dpif_linux_dp *dp, struct ofpbuf *buf)
}
/* Skip OVS_DP_ATTR_STATS since we never have a reason to serialize it. */
-
- if (dp->ipv4_frags) {
- nl_msg_put_u32(buf, OVS_DP_ATTR_IPV4_FRAGS, dp->ipv4_frags);
- }
}
/* Clears 'dp' to "empty" values. */