Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/jesse/openvswitch
Jesse Gross says: ==================== A few miscellaneous improvements and cleanups before the GRE tunnel integration series. Intended for net-next/3.11. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
@@ -192,7 +192,6 @@ enum ovs_vport_type {
|
|||||||
* optional; if not specified a free port number is automatically selected.
|
* optional; if not specified a free port number is automatically selected.
|
||||||
* Whether %OVS_VPORT_ATTR_OPTIONS is required or optional depends on the type
|
* Whether %OVS_VPORT_ATTR_OPTIONS is required or optional depends on the type
|
||||||
* of vport.
|
* of vport.
|
||||||
* and other attributes are ignored.
|
|
||||||
*
|
*
|
||||||
* For other requests, if %OVS_VPORT_ATTR_NAME is specified then it is used to
|
* For other requests, if %OVS_VPORT_ATTR_NAME is specified then it is used to
|
||||||
* look up the vport to operate on; otherwise dp_idx from the &struct
|
* look up the vport to operate on; otherwise dp_idx from the &struct
|
||||||
|
@@ -130,9 +130,13 @@ static int set_eth_addr(struct sk_buff *skb,
|
|||||||
if (unlikely(err))
|
if (unlikely(err))
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
skb_postpull_rcsum(skb, eth_hdr(skb), ETH_ALEN * 2);
|
||||||
|
|
||||||
memcpy(eth_hdr(skb)->h_source, eth_key->eth_src, ETH_ALEN);
|
memcpy(eth_hdr(skb)->h_source, eth_key->eth_src, ETH_ALEN);
|
||||||
memcpy(eth_hdr(skb)->h_dest, eth_key->eth_dst, ETH_ALEN);
|
memcpy(eth_hdr(skb)->h_dest, eth_key->eth_dst, ETH_ALEN);
|
||||||
|
|
||||||
|
ovs_skb_postpush_rcsum(skb, eth_hdr(skb), ETH_ALEN * 2);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -739,10 +739,7 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info)
|
|||||||
if (err)
|
if (err)
|
||||||
goto err_flow_free;
|
goto err_flow_free;
|
||||||
|
|
||||||
err = ovs_flow_metadata_from_nlattrs(&flow->key.phy.priority,
|
err = ovs_flow_metadata_from_nlattrs(flow, a[OVS_PACKET_ATTR_KEY]);
|
||||||
&flow->key.phy.skb_mark,
|
|
||||||
&flow->key.phy.in_port,
|
|
||||||
a[OVS_PACKET_ATTR_KEY]);
|
|
||||||
if (err)
|
if (err)
|
||||||
goto err_flow_free;
|
goto err_flow_free;
|
||||||
|
|
||||||
@@ -1812,10 +1809,11 @@ static int ovs_vport_cmd_set(struct sk_buff *skb, struct genl_info *info)
|
|||||||
if (IS_ERR(vport))
|
if (IS_ERR(vport))
|
||||||
goto exit_unlock;
|
goto exit_unlock;
|
||||||
|
|
||||||
err = 0;
|
|
||||||
if (a[OVS_VPORT_ATTR_TYPE] &&
|
if (a[OVS_VPORT_ATTR_TYPE] &&
|
||||||
nla_get_u32(a[OVS_VPORT_ATTR_TYPE]) != vport->ops->type)
|
nla_get_u32(a[OVS_VPORT_ATTR_TYPE]) != vport->ops->type) {
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
|
goto exit_unlock;
|
||||||
|
}
|
||||||
|
|
||||||
reply = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
|
reply = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
|
||||||
if (!reply) {
|
if (!reply) {
|
||||||
@@ -1823,10 +1821,11 @@ static int ovs_vport_cmd_set(struct sk_buff *skb, struct genl_info *info)
|
|||||||
goto exit_unlock;
|
goto exit_unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!err && a[OVS_VPORT_ATTR_OPTIONS])
|
if (a[OVS_VPORT_ATTR_OPTIONS]) {
|
||||||
err = ovs_vport_set_options(vport, a[OVS_VPORT_ATTR_OPTIONS]);
|
err = ovs_vport_set_options(vport, a[OVS_VPORT_ATTR_OPTIONS]);
|
||||||
if (err)
|
if (err)
|
||||||
goto exit_free;
|
goto exit_free;
|
||||||
|
}
|
||||||
|
|
||||||
if (a[OVS_VPORT_ATTR_UPCALL_PID])
|
if (a[OVS_VPORT_ATTR_UPCALL_PID])
|
||||||
vport->upcall_portid = nla_get_u32(a[OVS_VPORT_ATTR_UPCALL_PID]);
|
vport->upcall_portid = nla_get_u32(a[OVS_VPORT_ATTR_UPCALL_PID]);
|
||||||
|
@@ -590,10 +590,10 @@ out:
|
|||||||
* - skb->network_header: just past the Ethernet header, or just past the
|
* - skb->network_header: just past the Ethernet header, or just past the
|
||||||
* VLAN header, to the first byte of the Ethernet payload.
|
* VLAN header, to the first byte of the Ethernet payload.
|
||||||
*
|
*
|
||||||
* - skb->transport_header: If key->dl_type is ETH_P_IP or ETH_P_IPV6
|
* - skb->transport_header: If key->eth.type is ETH_P_IP or ETH_P_IPV6
|
||||||
* on output, then just past the IP header, if one is present and
|
* on output, then just past the IP header, if one is present and
|
||||||
* of a correct length, otherwise the same as skb->network_header.
|
* of a correct length, otherwise the same as skb->network_header.
|
||||||
* For other key->dl_type values it is left untouched.
|
* For other key->eth.type values it is left untouched.
|
||||||
*/
|
*/
|
||||||
int ovs_flow_extract(struct sk_buff *skb, u16 in_port, struct sw_flow_key *key,
|
int ovs_flow_extract(struct sk_buff *skb, u16 in_port, struct sw_flow_key *key,
|
||||||
int *key_lenp)
|
int *key_lenp)
|
||||||
@@ -618,6 +618,9 @@ int ovs_flow_extract(struct sk_buff *skb, u16 in_port, struct sw_flow_key *key,
|
|||||||
memcpy(key->eth.dst, eth->h_dest, ETH_ALEN);
|
memcpy(key->eth.dst, eth->h_dest, ETH_ALEN);
|
||||||
|
|
||||||
__skb_pull(skb, 2 * ETH_ALEN);
|
__skb_pull(skb, 2 * ETH_ALEN);
|
||||||
|
/* We are going to push all headers that we pull, so no need to
|
||||||
|
* update skb->csum here.
|
||||||
|
*/
|
||||||
|
|
||||||
if (vlan_tx_tag_present(skb))
|
if (vlan_tx_tag_present(skb))
|
||||||
key->eth.tci = htons(skb->vlan_tci);
|
key->eth.tci = htons(skb->vlan_tci);
|
||||||
@@ -1122,10 +1125,8 @@ int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* ovs_flow_metadata_from_nlattrs - parses Netlink attributes into a flow key.
|
* ovs_flow_metadata_from_nlattrs - parses Netlink attributes into a flow key.
|
||||||
* @priority: receives the skb priority
|
* @flow: Receives extracted in_port, priority, tun_key and skb_mark.
|
||||||
* @mark: receives the skb mark
|
* @attr: Netlink attribute holding nested %OVS_KEY_ATTR_* Netlink attribute
|
||||||
* @in_port: receives the extracted input port.
|
|
||||||
* @key: Netlink attribute holding nested %OVS_KEY_ATTR_* Netlink attribute
|
|
||||||
* sequence.
|
* sequence.
|
||||||
*
|
*
|
||||||
* This parses a series of Netlink attributes that form a flow key, which must
|
* This parses a series of Netlink attributes that form a flow key, which must
|
||||||
@@ -1133,15 +1134,15 @@ int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp,
|
|||||||
* get the metadata, that is, the parts of the flow key that cannot be
|
* get the metadata, that is, the parts of the flow key that cannot be
|
||||||
* extracted from the packet itself.
|
* extracted from the packet itself.
|
||||||
*/
|
*/
|
||||||
int ovs_flow_metadata_from_nlattrs(u32 *priority, u32 *mark, u16 *in_port,
|
int ovs_flow_metadata_from_nlattrs(struct sw_flow *flow,
|
||||||
const struct nlattr *attr)
|
const struct nlattr *attr)
|
||||||
{
|
{
|
||||||
const struct nlattr *nla;
|
const struct nlattr *nla;
|
||||||
int rem;
|
int rem;
|
||||||
|
|
||||||
*in_port = DP_MAX_PORTS;
|
flow->key.phy.in_port = DP_MAX_PORTS;
|
||||||
*priority = 0;
|
flow->key.phy.priority = 0;
|
||||||
*mark = 0;
|
flow->key.phy.skb_mark = 0;
|
||||||
|
|
||||||
nla_for_each_nested(nla, attr, rem) {
|
nla_for_each_nested(nla, attr, rem) {
|
||||||
int type = nla_type(nla);
|
int type = nla_type(nla);
|
||||||
@@ -1152,17 +1153,17 @@ int ovs_flow_metadata_from_nlattrs(u32 *priority, u32 *mark, u16 *in_port,
|
|||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case OVS_KEY_ATTR_PRIORITY:
|
case OVS_KEY_ATTR_PRIORITY:
|
||||||
*priority = nla_get_u32(nla);
|
flow->key.phy.priority = nla_get_u32(nla);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OVS_KEY_ATTR_IN_PORT:
|
case OVS_KEY_ATTR_IN_PORT:
|
||||||
if (nla_get_u32(nla) >= DP_MAX_PORTS)
|
if (nla_get_u32(nla) >= DP_MAX_PORTS)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
*in_port = nla_get_u32(nla);
|
flow->key.phy.in_port = nla_get_u32(nla);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OVS_KEY_ATTR_SKB_MARK:
|
case OVS_KEY_ATTR_SKB_MARK:
|
||||||
*mark = nla_get_u32(nla);
|
flow->key.phy.skb_mark = nla_get_u32(nla);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -141,8 +141,8 @@ u64 ovs_flow_used_time(unsigned long flow_jiffies);
|
|||||||
int ovs_flow_to_nlattrs(const struct sw_flow_key *, struct sk_buff *);
|
int ovs_flow_to_nlattrs(const struct sw_flow_key *, struct sk_buff *);
|
||||||
int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp,
|
int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp,
|
||||||
const struct nlattr *);
|
const struct nlattr *);
|
||||||
int ovs_flow_metadata_from_nlattrs(u32 *priority, u32 *mark, u16 *in_port,
|
int ovs_flow_metadata_from_nlattrs(struct sw_flow *flow,
|
||||||
const struct nlattr *);
|
const struct nlattr *attr);
|
||||||
|
|
||||||
#define MAX_ACTIONS_BUFSIZE (16 * 1024)
|
#define MAX_ACTIONS_BUFSIZE (16 * 1024)
|
||||||
#define TBL_MIN_BUCKETS 1024
|
#define TBL_MIN_BUCKETS 1024
|
||||||
|
@@ -221,6 +221,7 @@ static int internal_dev_recv(struct vport *vport, struct sk_buff *skb)
|
|||||||
skb->dev = netdev;
|
skb->dev = netdev;
|
||||||
skb->pkt_type = PACKET_HOST;
|
skb->pkt_type = PACKET_HOST;
|
||||||
skb->protocol = eth_type_trans(skb, netdev);
|
skb->protocol = eth_type_trans(skb, netdev);
|
||||||
|
skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
|
||||||
|
|
||||||
netif_rx(skb);
|
netif_rx(skb);
|
||||||
|
|
||||||
|
@@ -49,6 +49,8 @@ static void netdev_port_receive(struct vport *vport, struct sk_buff *skb)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
skb_push(skb, ETH_HLEN);
|
skb_push(skb, ETH_HLEN);
|
||||||
|
ovs_skb_postpush_rcsum(skb, skb->data, ETH_HLEN);
|
||||||
|
|
||||||
ovs_vport_receive(vport, skb);
|
ovs_vport_receive(vport, skb);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -170,7 +172,7 @@ static int netdev_send(struct vport *vport, struct sk_buff *skb)
|
|||||||
net_warn_ratelimited("%s: dropped over-mtu packet: %d > %d\n",
|
net_warn_ratelimited("%s: dropped over-mtu packet: %d > %d\n",
|
||||||
netdev_vport->dev->name,
|
netdev_vport->dev->name,
|
||||||
packet_length(skb), mtu);
|
packet_length(skb), mtu);
|
||||||
goto error;
|
goto drop;
|
||||||
}
|
}
|
||||||
|
|
||||||
skb->dev = netdev_vport->dev;
|
skb->dev = netdev_vport->dev;
|
||||||
@@ -179,9 +181,8 @@ static int netdev_send(struct vport *vport, struct sk_buff *skb)
|
|||||||
|
|
||||||
return len;
|
return len;
|
||||||
|
|
||||||
error:
|
drop:
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
ovs_vport_record_error(vport, VPORT_E_TX_DROPPED);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -39,6 +39,5 @@ netdev_vport_priv(const struct vport *vport)
|
|||||||
}
|
}
|
||||||
|
|
||||||
const char *ovs_netdev_get_name(const struct vport *);
|
const char *ovs_netdev_get_name(const struct vport *);
|
||||||
const char *ovs_netdev_get_config(const struct vport *);
|
|
||||||
|
|
||||||
#endif /* vport_netdev.h */
|
#endif /* vport_netdev.h */
|
||||||
|
@@ -351,7 +351,7 @@ int ovs_vport_send(struct vport *vport, struct sk_buff *skb)
|
|||||||
{
|
{
|
||||||
int sent = vport->ops->send(vport, skb);
|
int sent = vport->ops->send(vport, skb);
|
||||||
|
|
||||||
if (likely(sent)) {
|
if (likely(sent > 0)) {
|
||||||
struct pcpu_tstats *stats;
|
struct pcpu_tstats *stats;
|
||||||
|
|
||||||
stats = this_cpu_ptr(vport->percpu_stats);
|
stats = this_cpu_ptr(vport->percpu_stats);
|
||||||
@@ -360,7 +360,12 @@ int ovs_vport_send(struct vport *vport, struct sk_buff *skb)
|
|||||||
stats->tx_packets++;
|
stats->tx_packets++;
|
||||||
stats->tx_bytes += sent;
|
stats->tx_bytes += sent;
|
||||||
u64_stats_update_end(&stats->syncp);
|
u64_stats_update_end(&stats->syncp);
|
||||||
}
|
} else if (sent < 0) {
|
||||||
|
ovs_vport_record_error(vport, VPORT_E_TX_ERROR);
|
||||||
|
kfree_skb(skb);
|
||||||
|
} else
|
||||||
|
ovs_vport_record_error(vport, VPORT_E_TX_DROPPED);
|
||||||
|
|
||||||
return sent;
|
return sent;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -371,7 +376,7 @@ int ovs_vport_send(struct vport *vport, struct sk_buff *skb)
|
|||||||
* @err_type: one of enum vport_err_type types to indicate the error type
|
* @err_type: one of enum vport_err_type types to indicate the error type
|
||||||
*
|
*
|
||||||
* If using the vport generic stats layer indicate that an error of the given
|
* If using the vport generic stats layer indicate that an error of the given
|
||||||
* type has occured.
|
* type has occurred.
|
||||||
*/
|
*/
|
||||||
void ovs_vport_record_error(struct vport *vport, enum vport_err_type err_type)
|
void ovs_vport_record_error(struct vport *vport, enum vport_err_type err_type)
|
||||||
{
|
{
|
||||||
|
@@ -123,9 +123,8 @@ struct vport_parms {
|
|||||||
* existing vport to a &struct sk_buff. May be %NULL for a vport that does not
|
* existing vport to a &struct sk_buff. May be %NULL for a vport that does not
|
||||||
* have any configuration.
|
* have any configuration.
|
||||||
* @get_name: Get the device's name.
|
* @get_name: Get the device's name.
|
||||||
* @get_config: Get the device's configuration.
|
* @send: Send a packet on the device. Returns the length of the packet sent,
|
||||||
* May be null if the device does not have an ifindex.
|
* zero for dropped packets or negative for error.
|
||||||
* @send: Send a packet on the device. Returns the length of the packet sent.
|
|
||||||
*/
|
*/
|
||||||
struct vport_ops {
|
struct vport_ops {
|
||||||
enum ovs_vport_type type;
|
enum ovs_vport_type type;
|
||||||
@@ -139,7 +138,6 @@ struct vport_ops {
|
|||||||
|
|
||||||
/* Called with rcu_read_lock or ovs_mutex. */
|
/* Called with rcu_read_lock or ovs_mutex. */
|
||||||
const char *(*get_name)(const struct vport *);
|
const char *(*get_name)(const struct vport *);
|
||||||
void (*get_config)(const struct vport *, void *);
|
|
||||||
|
|
||||||
int (*send)(struct vport *, struct sk_buff *);
|
int (*send)(struct vport *, struct sk_buff *);
|
||||||
};
|
};
|
||||||
@@ -194,4 +192,11 @@ void ovs_vport_record_error(struct vport *, enum vport_err_type err_type);
|
|||||||
extern const struct vport_ops ovs_netdev_vport_ops;
|
extern const struct vport_ops ovs_netdev_vport_ops;
|
||||||
extern const struct vport_ops ovs_internal_vport_ops;
|
extern const struct vport_ops ovs_internal_vport_ops;
|
||||||
|
|
||||||
|
static inline void ovs_skb_postpush_rcsum(struct sk_buff *skb,
|
||||||
|
const void *start, unsigned int len)
|
||||||
|
{
|
||||||
|
if (skb->ip_summed == CHECKSUM_COMPLETE)
|
||||||
|
skb->csum = csum_add(skb->csum, csum_partial(start, len, 0));
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* vport.h */
|
#endif /* vport.h */
|
||||||
|
Reference in New Issue
Block a user