X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=datapath%2Fdatapath.c;h=940a58142dbef97ad0881fdfc308f6640122d361;hb=740bc6a4f2d70cb9c4d362895d26948820bdca79;hp=89b0d7f0c09f6b6ea06ea71a715344f8246f6d48;hpb=47e0120572fdca82f2e97b82bee5ff2e36b6c93e;p=openvswitch diff --git a/datapath/datapath.c b/datapath/datapath.c index 89b0d7f0..940a5814 100644 --- a/datapath/datapath.c +++ b/datapath/datapath.c @@ -51,6 +51,7 @@ #include "flow.h" #include "loop_counter.h" #include "table.h" +#include "vlan.h" #include "vport-internal_dev.h" int (*dp_ioctl_hook)(struct net_device *dev, struct ifreq *rq, int cmd); @@ -483,6 +484,10 @@ static int queue_control_packets(struct datapath *dp, struct sk_buff *skb, nskb = skb->next; skb->next = NULL; + err = vlan_deaccel_tag(skb); + if (unlikely(err)) + goto err_kfree_skbs; + len = sizeof(struct odp_header); len += nla_total_size(skb->len); len += nla_total_size(FLOW_BUFSIZE); @@ -773,6 +778,8 @@ int dp_min_mtu(const struct datapath *dp) continue; dev_mtu = vport_get_mtu(p); + if (!dev_mtu) + continue; if (!mtu || dev_mtu < mtu) mtu = dev_mtu; } @@ -827,7 +834,6 @@ static int odp_flow_cmd_fill_info(struct sw_flow *flow, struct datapath *dp, struct nlattr *nla; unsigned long used; u8 tcp_flags; - int nla_len; int err; sf_acts = rcu_dereference_protected(flow->sf_acts, @@ -855,7 +861,7 @@ static int odp_flow_cmd_fill_info(struct sw_flow *flow, struct datapath *dp, spin_unlock_bh(&flow->lock); if (used) - NLA_PUT_MSECS(skb, ODP_FLOW_ATTR_USED, used); + NLA_PUT_U64(skb, ODP_FLOW_ATTR_USED, flow_used_time(used)); if (stats.n_packets) NLA_PUT(skb, ODP_FLOW_ATTR_STATS, sizeof(struct odp_flow_stats), &stats); @@ -863,23 +869,20 @@ static int odp_flow_cmd_fill_info(struct sw_flow *flow, struct datapath *dp, if (tcp_flags) NLA_PUT_U8(skb, ODP_FLOW_ATTR_TCP_FLAGS, tcp_flags); - /* If ODP_FLOW_ATTR_ACTIONS doesn't fit, and this is the first flow to - * be dumped into 'skb', then expand the skb. This is unusual for - * Netlink but individual action lists can be longer than a page and - * thus entirely undumpable if we didn't do this. */ - nla_len = nla_total_size(sf_acts->actions_len); - if (nla_len > skb_tailroom(skb) && !skb_orig_len) { - int hdr_off = (unsigned char *)odp_header - skb->data; - - err = pskb_expand_head(skb, 0, nla_len - skb_tailroom(skb), GFP_KERNEL); - if (err) - goto error; - - odp_header = (struct odp_header *)(skb->data + hdr_off); - } - nla = nla_nest_start(skb, ODP_FLOW_ATTR_ACTIONS); - memcpy(__skb_put(skb, sf_acts->actions_len), sf_acts->actions, sf_acts->actions_len); - nla_nest_end(skb, nla); + /* If ODP_FLOW_ATTR_ACTIONS doesn't fit, skip dumping the actions if + * this is the first flow to be dumped into 'skb'. This is unusual for + * Netlink but individual action lists can be longer than + * NLMSG_GOODSIZE and thus entirely undumpable if we didn't do this. + * The userspace caller can always fetch the actions separately if it + * really wants them. (Most userspace callers in fact don't care.) + * + * This can only fail for dump operations because the skb is always + * properly sized for single flows. + */ + err = nla_put(skb, ODP_FLOW_ATTR_ACTIONS, sf_acts->actions_len, + sf_acts->actions); + if (err < 0 && skb_orig_len) + goto error; return genlmsg_end(skb, odp_header); @@ -1586,6 +1589,7 @@ static int odp_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb, struct odp_header *odp_header; struct nlattr *nla; int ifindex, iflink; + int mtu; int err; odp_header = genlmsg_put(skb, pid, seq, &dp_vport_genl_family, @@ -1607,7 +1611,9 @@ static int odp_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb, NLA_PUT(skb, ODP_VPORT_ATTR_ADDRESS, ETH_ALEN, vport_get_addr(vport)); - NLA_PUT_U32(skb, ODP_VPORT_ATTR_MTU, vport_get_mtu(vport)); + mtu = vport_get_mtu(vport); + if (mtu) + NLA_PUT_U32(skb, ODP_VPORT_ATTR_MTU, mtu); err = vport_get_options(vport, skb); if (err == -EMSGSIZE)