projects
/
openvswitch
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
bridge: Optimize port_lookup() using a hash.
[openvswitch]
/
lib
/
dpif-netdev.c
diff --git
a/lib/dpif-netdev.c
b/lib/dpif-netdev.c
index e19cb34a272076c576b02674a1a0c37204a6cd39..2f4463e6d4783851a1d1d01615b8b53da0c5d462 100644
(file)
--- a/
lib/dpif-netdev.c
+++ b/
lib/dpif-netdev.c
@@
-720,58
+720,64
@@
static int
dpif_netdev_validate_actions(const union odp_action *actions, int n_actions,
bool *mutates)
{
dpif_netdev_validate_actions(const union odp_action *actions, int n_actions,
bool *mutates)
{
-
unsigned int i;
+ unsigned int i;
*mutates = false;
*mutates = false;
-
for (i = 0; i < n_actions; i++) {
-
const union odp_action *a = &actions[i];
-
switch (a->type) {
-
case ODPAT_OUTPUT:
-
if (a->output.port >= MAX_PORTS) {
-
return EINVAL;
+ for (i = 0; i < n_actions; i++) {
+ const union odp_action *a = &actions[i];
+ switch (a->type) {
+ case ODPAT_OUTPUT:
+ if (a->output.port >= MAX_PORTS) {
+ return EINVAL;
}
}
-
break;
+ break;
-
case ODPAT_OUTPUT_GROUP:
+ case ODPAT_OUTPUT_GROUP:
*mutates = true;
*mutates = true;
-
if (a->output_group.group >= N_GROUPS) {
-
return EINVAL;
+ if (a->output_group.group >= N_GROUPS) {
+ return EINVAL;
}
}
-
break;
+ break;
case ODPAT_CONTROLLER:
break;
case ODPAT_CONTROLLER:
break;
-
case ODPAT_SET_VLAN_VID:
+ case ODPAT_SET_VLAN_VID:
*mutates = true;
*mutates = true;
-
if (a->vlan_vid.vlan_vid & htons(~VLAN_VID_MASK)) {
-
return EINVAL;
+ if (a->vlan_vid.vlan_vid & htons(~VLAN_VID_MASK)) {
+ return EINVAL;
}
}
-
break;
+ break;
-
case ODPAT_SET_VLAN_PCP:
+ case ODPAT_SET_VLAN_PCP:
*mutates = true;
*mutates = true;
-
if (a->vlan_pcp.vlan_pcp & ~(VLAN_PCP_MASK >> VLAN_PCP_SHIFT)) {
-
return EINVAL;
+ if (a->vlan_pcp.vlan_pcp & ~(VLAN_PCP_MASK >> VLAN_PCP_SHIFT)) {
+ return EINVAL;
}
}
- break;
+ break;
+
+ case ODPAT_SET_NW_TOS:
+ *mutates = true;
+ if (a->nw_tos.nw_tos & IP_ECN_MASK) {
+ return EINVAL;
+ }
+ break;
case ODPAT_STRIP_VLAN:
case ODPAT_SET_DL_SRC:
case ODPAT_SET_DL_DST:
case ODPAT_SET_NW_SRC:
case ODPAT_SET_NW_DST:
case ODPAT_STRIP_VLAN:
case ODPAT_SET_DL_SRC:
case ODPAT_SET_DL_DST:
case ODPAT_SET_NW_SRC:
case ODPAT_SET_NW_DST:
- case ODPAT_SET_NW_TOS:
case ODPAT_SET_TP_SRC:
case ODPAT_SET_TP_DST:
*mutates = true;
break;
case ODPAT_SET_TP_SRC:
case ODPAT_SET_TP_DST:
*mutates = true;
break;
-
default:
+ default:
return EOPNOTSUPP;
return EOPNOTSUPP;
-
}
-
}
-
return 0;
+ }
+ }
+ return 0;
}
static int
}
static int
@@
-926,7
+932,7
@@
dpif_netdev_execute(struct dpif *dpif, uint16_t in_port,
* if we don't. */
copy = *packet;
}
* if we don't. */
copy = *packet;
}
- flow_extract(©, in_port, &flow);
+ flow_extract(©,
0,
in_port, &flow);
error = dp_netdev_execute_actions(dp, ©, &flow, actions, n_actions);
if (mutates) {
ofpbuf_uninit(©);
error = dp_netdev_execute_actions(dp, ©, &flow, actions, n_actions);
if (mutates) {
ofpbuf_uninit(©);
@@
-1020,7
+1026,7
@@
dp_netdev_port_input(struct dp_netdev *dp, struct dp_netdev_port *port,
struct dp_netdev_flow *flow;
flow_t key;
struct dp_netdev_flow *flow;
flow_t key;
- if (flow_extract(packet, port->port_no, &key) && dp->drop_frags) {
+ if (flow_extract(packet,
0,
port->port_no, &key) && dp->drop_frags) {
dp->n_frags++;
return;
}
dp->n_frags++;
return;
}
@@
-1139,19
+1145,21
@@
dp_netdev_strip_vlan(struct ofpbuf *packet, flow_t *key)
}
static void
}
static void
-dp_netdev_set_dl_src(struct ofpbuf *packet,
+dp_netdev_set_dl_src(struct ofpbuf *packet,
flow_t *key,
const uint8_t dl_addr[ETH_ADDR_LEN])
{
struct eth_header *eh = packet->l2;
memcpy(eh->eth_src, dl_addr, sizeof eh->eth_src);
const uint8_t dl_addr[ETH_ADDR_LEN])
{
struct eth_header *eh = packet->l2;
memcpy(eh->eth_src, dl_addr, sizeof eh->eth_src);
+ memcpy(key->dl_src, dl_addr, sizeof key->dl_src);
}
static void
}
static void
-dp_netdev_set_dl_dst(struct ofpbuf *packet,
+dp_netdev_set_dl_dst(struct ofpbuf *packet,
flow_t *key,
const uint8_t dl_addr[ETH_ADDR_LEN])
{
struct eth_header *eh = packet->l2;
memcpy(eh->eth_dst, dl_addr, sizeof eh->eth_dst);
const uint8_t dl_addr[ETH_ADDR_LEN])
{
struct eth_header *eh = packet->l2;
memcpy(eh->eth_dst, dl_addr, sizeof eh->eth_dst);
+ memcpy(key->dl_dst, dl_addr, sizeof key->dl_dst);
}
static void
}
static void
@@
-1177,6
+1185,12
@@
dp_netdev_set_nw_addr(struct ofpbuf *packet, flow_t *key,
}
nh->ip_csum = recalc_csum32(nh->ip_csum, *field, a->nw_addr);
*field = a->nw_addr;
}
nh->ip_csum = recalc_csum32(nh->ip_csum, *field, a->nw_addr);
*field = a->nw_addr;
+
+ if (a->type == ODPAT_SET_NW_SRC) {
+ key->nw_src = a->type;
+ } else {
+ key->nw_dst = a->type;
+ }
}
}
}
}
@@
-1189,11
+1203,12
@@
dp_netdev_set_nw_tos(struct ofpbuf *packet, flow_t *key,
uint8_t *field = &nh->ip_tos;
/* Set the DSCP bits and preserve the ECN bits. */
uint8_t *field = &nh->ip_tos;
/* Set the DSCP bits and preserve the ECN bits. */
- uint8_t new =
(a->nw_tos & IP_DSCP_MASK)
| (nh->ip_tos & IP_ECN_MASK);
+ uint8_t new =
a->nw_tos
| (nh->ip_tos & IP_ECN_MASK);
nh->ip_csum = recalc_csum16(nh->ip_csum, htons((uint16_t)*field),
htons((uint16_t)a->nw_tos));
*field = new;
nh->ip_csum = recalc_csum16(nh->ip_csum, htons((uint16_t)*field),
htons((uint16_t)a->nw_tos));
*field = new;
+ key->nw_tos = a->nw_tos;
}
}
}
}
@@
-1213,6
+1228,14
@@
dp_netdev_set_tp_port(struct ofpbuf *packet, flow_t *key,
field = a->type == ODPAT_SET_TP_SRC ? &uh->udp_src : &uh->udp_dst;
uh->udp_csum = recalc_csum16(uh->udp_csum, *field, a->tp_port);
*field = a->tp_port;
field = a->type == ODPAT_SET_TP_SRC ? &uh->udp_src : &uh->udp_dst;
uh->udp_csum = recalc_csum16(uh->udp_csum, *field, a->tp_port);
*field = a->tp_port;
+ } else {
+ return;
+ }
+
+ if (a->type == ODPAT_SET_TP_SRC) {
+ key->tp_src = a->tp_port;
+ } else {
+ key->tp_dst = a->tp_port;
}
}
}
}
}
}
@@
-1257,7
+1280,8
@@
dp_netdev_output_control(struct dp_netdev *dp, const struct ofpbuf *packet,
}
msg_size = sizeof *header + packet->size;
}
msg_size = sizeof *header + packet->size;
- msg = ofpbuf_new(msg_size);
+ msg = ofpbuf_new(msg_size + DPIF_RECV_MSG_PADDING);
+ ofpbuf_reserve(msg, DPIF_RECV_MSG_PADDING);
header = ofpbuf_put_uninit(msg, sizeof *header);
header->type = queue_no;
header->length = msg_size;
header = ofpbuf_put_uninit(msg, sizeof *header);
header->type = queue_no;
header->length = msg_size;
@@
-1309,11
+1333,11
@@
dp_netdev_execute_actions(struct dp_netdev *dp,
break;
case ODPAT_SET_DL_SRC:
break;
case ODPAT_SET_DL_SRC:
- dp_netdev_set_dl_src(packet, a->dl_addr.dl_addr);
+ dp_netdev_set_dl_src(packet,
key,
a->dl_addr.dl_addr);
break;
case ODPAT_SET_DL_DST:
break;
case ODPAT_SET_DL_DST:
- dp_netdev_set_dl_dst(packet, a->dl_addr.dl_addr);
+ dp_netdev_set_dl_dst(packet,
key,
a->dl_addr.dl_addr);
break;
case ODPAT_SET_NW_SRC:
break;
case ODPAT_SET_NW_SRC: