socsvn commit: r337279 - soc2018/sduo/head/sys/dev/vale_vlan
sduo at FreeBSD.org
sduo at FreeBSD.org
Thu Aug 2 10:26:04 UTC 2018
Author: sduo
Date: Thu Aug 2 10:26:00 2018
New Revision: 337279
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=337279
Log:
Updated vale_vlan files.
Modified:
soc2018/sduo/head/sys/dev/vale_vlan/vale_vlan.c
Modified: soc2018/sduo/head/sys/dev/vale_vlan/vale_vlan.c
==============================================================================
--- soc2018/sduo/head/sys/dev/vale_vlan/vale_vlan.c Thu Aug 2 10:14:21 2018 (r337278)
+++ soc2018/sduo/head/sys/dev/vale_vlan/vale_vlan.c Thu Aug 2 10:26:00 2018 (r337279)
@@ -12,60 +12,90 @@
tag_frame(struct nm_bdg_fwd *ft, struct netmap_vp_adapter *vpna,
uint16_t vlan_id)
{
- struct nm_bdg_fwd *ft_end = ft + ft->ft_frags - 1;
- struct nm_bdg_fwd *ft_cur = NULL;
- uint8_t *buf = NULL;
- uint32_t buf_size;
uint16_t be_tpid;
uint16_t be_tci; /* at the moment PCP and DEI are always set to 0 */
- int n_bytes = 0;
+ char *buf;
- buf_size = NETMAP_BUF_SIZE((struct netmap_adapter *)vpna);
- if (ft_end->ft_len + TAG_LENGTH > buf_size) {
- nm_prinf("Not enough space for the tag in the last fragment\n");
- return EINVAL;
- }
- if (ft->ft_offset + TAG_END > ft->ft_len) {
+ if (ft->ft_virtio_offset + TAG_END > ft->ft_len) {
nm_prinf("Header split between two nm_bdg_fwd,"
"at the moment not supported\n");
return EINVAL;
}
- ft_end->ft_len += TAG_LENGTH;
- for (ft_cur = ft_end; ft_cur != ft - 1; --ft_cur) {
- uint8_t *start_addr = NULL;
- uint8_t *dest_addr = NULL;
- uint16_t buf_len = ft_cur->ft_len;
- buf = ft_cur->ft_buf;
+ if (likely(ft->ft_head_space >= TAG_LENGTH)) {
+ /* Best case: the netmap slot has an offset >= TAG_LENGTH,
+ * thus we can just move the virtio-net header + MAC addresses
+ * back by TAG_LENGTH bytes
+ */
+ if (ft->ft_flags & NS_INDIRECT) {
+ return EINVAL;
+ }
- if (ft_cur->ft_flags & NS_INDIRECT) {
+ buf = (char *)ft->ft_buf - TAG_LENGTH;
+ memmove(buf, ft->ft_buf, TAG_START + ft->ft_virtio_offset);
+ ft->ft_head_space -= TAG_LENGTH;
+ ft->ft_len += TAG_LENGTH;
+ ft->ft_buf = buf;
+ } else {
+ /* Worst case: we need to move everything forward by
+ * TAG_LENGTH bytes.
+ */
+ struct nm_bdg_fwd *ft_end = ft + ft->ft_frags - 1;
+ uint32_t buf_size =
+ NETMAP_BUF_SIZE(&vpna->up, ft->ft_head_space);
+ struct nm_bdg_fwd *ft_cur;
+
+ if (ft_end->ft_len + ft_end->ft_head_space + TAG_LENGTH >
+ buf_size) {
+ nm_prinf("Not enough space for the tag in the last "
+ "fragment\n");
return EINVAL;
}
- if (ft_cur != ft_end) {
- /* copy 4 bytes from the end of the current buffer
- * to the beginning of the next buffer
+ ft_end->ft_len += TAG_LENGTH;
+
+ for (ft_cur = ft_end; ft_cur != ft - 1; --ft_cur) {
+ uint16_t buf_len = ft_cur->ft_len;
+ uint8_t *start_addr;
+ uint8_t *dest_addr;
+ int n_bytes;
+
+ if (ft_cur->ft_flags & NS_INDIRECT) {
+ return EINVAL;
+ }
+
+ buf = ft_cur->ft_buf;
+ if (ft_cur != ft_end) {
+ /* copy 4 bytes from the end of the current
+ * buffer
+ * to the beginning of the next buffer
+ */
+ uint8_t *next_buf = (ft_cur + 1)->ft_buf;
+
+ start_addr = buf + buf_len - TAG_LENGTH;
+ dest_addr = next_buf;
+ *(uint32_t *)dest_addr =
+ *(uint32_t *)start_addr;
+ }
+
+ start_addr = buf + ft_cur->ft_virtio_offset;
+ dest_addr = start_addr + TAG_LENGTH;
+ /* we already added TAG_LENGTH to ft_end->ft_len,
+ * therefore the
+ * last fragment case is covered without any additional
+ * check
*/
- uint8_t *next_buf = (ft_cur + 1)->ft_buf;
- start_addr = buf + buf_len - TAG_LENGTH;
- dest_addr = next_buf;
- *(uint32_t *)dest_addr = *(uint32_t *)start_addr;
+ n_bytes =
+ buf_len - TAG_LENGTH - ft_cur->ft_virtio_offset;
+ memmove(dest_addr, start_addr, n_bytes);
}
-
- start_addr = buf + ft_cur->ft_offset;
- dest_addr = start_addr + TAG_LENGTH;
- /* we already added TAG_LENGTH to ft_end->ft_len, therefore the
- * last fragment case is covered without any additional check
- */
- n_bytes = buf_len - TAG_LENGTH - ft_cur->ft_offset;
- memmove(dest_addr, start_addr, n_bytes);
}
/* now we need to write the tag */
- be_tpid = htobe16(0x8100);
- be_tci = htobe16(vlan_id);
- buf = ft->ft_buf;
- *(uint16_t *)(buf + ft->ft_offset + TAG_PID) = be_tpid;
- *(uint16_t *)(buf + ft->ft_offset + TAG_CI) = be_tci;
+ be_tpid = htobe16(0x8100);
+ be_tci = htobe16(vlan_id);
+ buf = (char *)ft->ft_buf + ft->ft_virtio_offset;
+ *(uint16_t *)(buf + TAG_PID) = be_tpid;
+ *(uint16_t *)(buf + TAG_CI) = be_tci;
return 0;
}
@@ -74,28 +104,21 @@
untag_frame(struct nm_bdg_fwd *ft, struct netmap_vp_adapter *vpna,
uint16_t *vlan_id)
{
- struct nm_bdg_fwd *ft_end = ft + ft->ft_frags - 1;
- struct nm_bdg_fwd *ft_cur = NULL;
- uint8_t *buf = NULL;
uint16_t be_tpid;
uint16_t be_tci;
- int n_bytes = 0;
+ char *buf;
- if (ft->ft_offset + TAG_END > ft->ft_len) {
- /* VLAN header not contained in the first fragment */
+ if (ft->ft_virtio_offset + TAG_END > ft->ft_len) {
+ /* VLAN header not contained in the first fragment. */
return EINVAL;
}
- if (ft_end->ft_len < TAG_LENGTH) {
- /* During the untagging we strip TAG_LENGTH bytes from the
- * frame, therefore in this case last fragment would become
- * empty and we would need to update fragmentation flags etc.
- * At the moment we don't handle this case.
- */
+ if (ft->ft_flags & NS_INDIRECT) {
+ /* At the moment indirect buffers are not supported. */
return EINVAL;
}
- /* first we retrieve the informations we need */
- buf = (uint8_t *)ft->ft_buf + ft->ft_offset;
+ /* Retrieve informations from IEEE 802.1Q header */
+ buf = (char *)ft->ft_buf + ft->ft_virtio_offset;
be_tpid = *(uint16_t *)(buf + TAG_PID);
if (be_tpid != htobe16(0x8100)) {
nm_prinf("Not an IEEE802.Q frame\n");
@@ -104,37 +127,12 @@
be_tci = *(uint16_t *)(buf + TAG_CI);
*vlan_id = be16toh(be_tci) & 0x0FFF;
- /* then we remove the tag */
- for (ft_cur = ft; ft_cur != ft_end + 1; ++ft_cur) {
- uint8_t *start_addr = NULL;
- uint8_t *dest_addr = NULL;
- uint16_t buf_len = ft_cur->ft_len;
- buf = ft_cur->ft_buf;
-
- if (ft_cur->ft_flags & NS_INDIRECT) {
- /* we do not support indirect userspace buffers */
- return EINVAL;
- }
- if (ft_cur != ft) {
- /* copy 4 bytes from the start of the current buffer
- * to the end of the previous buffer
- */
- struct nm_bdg_fwd *prev_ft = ft_cur - 1;
- uint8_t *prev_buf = prev_ft->ft_buf;
- uint16_t prev_buf_len = prev_ft->ft_len;
-
- start_addr = buf;
- dest_addr = prev_buf + prev_buf_len - TAG_LENGTH;
- *(uint32_t *)dest_addr = *(uint32_t *)start_addr;
- }
+ /* Remove IEEE 802.1Q header */
+ buf = (char *)ft->ft_buf + TAG_LENGTH;
+ memmove(buf, ft->ft_buf, ft->ft_virtio_offset + TAG_START);
+ ft->ft_buf = buf;
+ ft->ft_len -= TAG_LENGTH;
- dest_addr = buf + ft->ft_offset;
- start_addr = dest_addr + TAG_LENGTH;
- n_bytes = buf_len - TAG_LENGTH - ft->ft_offset;
- memmove(dest_addr, start_addr, n_bytes);
- }
-
- ft_end->ft_len -= TAG_LENGTH;
return 0;
}
@@ -156,6 +154,9 @@
{
int i;
+ // nm_prinf("Initializing lookup data %p, NM_BDG_MAXPORTS = %d\n",
+ // l_data, NM_BDG_MAXPORTS);
+
l_data->trunk_port = NM_BDG_NOPORT;
for (i = 0; i < NM_BDG_MAXPORTS; ++i) {
l_data->port_to_vlan_id[i] = 0x000;
@@ -191,7 +192,6 @@
get_vlan_bdg_name(char *bridge_name, size_t len, const char *conf_name,
uint16_t vlan_id)
{
-
snprintf(bridge_name, len, "valeV%d%s:", vlan_id, conf_name);
}
@@ -199,7 +199,6 @@
get_ap_name(char *port_name, size_t len, const char *conf_name,
uint16_t vlan_id)
{
-
snprintf(port_name, len, "%sAP%d", conf_name, vlan_id);
}
@@ -209,14 +208,12 @@
static inline void
get_tagging_bdg_name(char *bridge_name, size_t len, const char *conf_name)
{
-
snprintf(bridge_name, len, "valeV%sTP:", conf_name);
}
static void
initialize_conf(struct vale_vlan_conf *conf)
{
-
initialize_lookup_data(&(conf->l_data));
conf->conf_name[0] = '\0';
bzero(conf->vlan_bdg_auth_tokens, sizeof(conf->vlan_bdg_auth_tokens));
@@ -237,6 +234,9 @@
int ret = 0;
bdg_name = netmap_bdg_name(vpna);
+ // nm_prinf("vlan_lookup for %s:%s\n", bdg_name, vpna->up.name);
+ // nm_prinf("lookup data = %p\n", lookup_data);
+ // nm_prinf("vpna = %p, bdg_port = %u\n", vpna, bdg_port);
if (unlikely(ft->ft_flags & NS_INDIRECT)) {
/* we do not handle userspace indirect buffers */
@@ -244,6 +244,7 @@
}
if (bdg_port == l_data->trunk_port) {
+ // nm_prinf("%s is a trunk port\n", vpna->up.name);
ret = untag_frame(ft, vpna, &vlan_id);
if (ret) {
return NM_BDG_NOPORT;
@@ -251,6 +252,8 @@
dest_port = l_data->vlan_id_to_port[vlan_id];
} else {
+ // nm_prinf("%s is an access port\n",
+ // vpna->up.name);
vlan_id = l_data->port_to_vlan_id[bdg_port];
ret = tag_frame(ft, vpna, vlan_id);
if (ret) {
@@ -271,6 +274,7 @@
nm_prinf("Trying to modify bdg %s for conf %s\n", bdg_name,
conf->conf_name);
+ // nm_prinf("lookup data = %p\n", &conf->l_data);
return netmap_bdg_regops(bdg_name, &vlan_ops, &conf->l_data,
conf->mod_bdg_auth_token);
}
@@ -346,7 +350,7 @@
nm_prerr("Error %d during bridge %s regops()\n", ret,
tagging_bdg_name);
ret2 = netmap_vale_destroy(tagging_bdg_name,
- conf->mod_bdg_auth_token);
+ conf->mod_bdg_auth_token);
if (ret2) {
/* cannot happen */
nm_prerr("Error %d during bridge %s destroy(), "
@@ -506,7 +510,7 @@
hdr.nr_name[sizeof(hdr.nr_name) - 1] = '\0';
bzero(&newif, sizeof(newif));
- hdr.nr_body = (uintptr_t)&newif;
+ hdr.nr_body = (uint64_t)(uintptr_t)&newif;
ret = nm_vi_create(&hdr);
if (ret == 0) {
@@ -593,7 +597,7 @@
bzero(&hdr, sizeof(hdr));
hdr.nr_version = NM_API_VERSION;
hdr.nr_reqtype = NETMAP_REQ_VALE_ATTACH;
- hdr.nr_body = (uintptr_t)&nmr_att;
+ hdr.nr_body = (uint64_t)(uintptr_t)&nmr_att;
snprintf(hdr.nr_name, sizeof(hdr.nr_name), "%s%s", bdg_name, port_name);
ret = nm_bdg_ctl_attach(&hdr, auth_token);
@@ -618,7 +622,7 @@
bzero(&hdr, sizeof(hdr));
hdr.nr_version = NM_API_VERSION;
hdr.nr_reqtype = NETMAP_REQ_VALE_DETACH;
- hdr.nr_body = (uintptr_t)&nmr_det;
+ hdr.nr_body = (uint64_t)(uintptr_t)&nmr_det;
snprintf(hdr.nr_name, sizeof(hdr.nr_name), "%s%s", bdg_name, port_name);
ret = nm_bdg_ctl_detach(&hdr, auth_token);
@@ -1198,50 +1202,39 @@
int
vv_read(struct vale_vlan_dev *dev, uint8_t *buf, size_t *len)
{
+ struct vale_vlan_conf *conf;
+ struct port_elem *p_elem;
+ size_t ret = 0;
if (dev->selected_conf == -1) {
return EINVAL;
}
- if (dev->error_entry != -1) {
- /* error read() */
- if (*len != sizeof(dev->error_entry)) {
- nm_prerr("After receiving an error from a write() call,"
- " read() must receive a int32_t pointer\n");
- return EINVAL;
- }
-
- memcpy(buf, &dev->error_entry, sizeof(dev->error_entry));
- *len = sizeof(dev->error_entry);
- dev->error_entry = -1;
- } else {
- /* conf read() */
- struct vale_vlan_conf *conf;
- struct port_elem *p_elem;
- size_t ret = 0;
-
- if (*len % sizeof(struct port) != 0) {
- nm_prerr("read() must receive an array of "
- "'struct vlan_conf_entry'\n");
- return EINVAL;
- }
+ if (*len % sizeof(struct port) != 0) {
+ nm_prerr("read() must receive an array of "
+ "'struct vlan_conf_entry'\n");
+ return EINVAL;
+ }
- conf = &vlan_confs[dev->selected_conf];
- vv_list_foreach(p_elem, &conf->port_list, list)
- {
- if (*len < ret + sizeof(struct port)) {
- *len = ret;
- return 0;
- }
- memcpy(buf, &p_elem->port_desc,
- sizeof(p_elem->port_desc));
- ret += sizeof(struct port);
- buf += sizeof(struct port);
+ conf = &vlan_confs[dev->selected_conf];
+ vv_list_foreach(p_elem, &conf->port_list, list)
+ {
+ if (*len < ret + sizeof(struct port)) {
+ /* At the moment we don't keep track of what
+ * we have read between multiple read() calls,
+ * therefore a configuration must be read in
+ * a single read() call.
+ */
+ *len = ret;
+ return 0;
}
- *len = ret;
+ memcpy(buf, &p_elem->port_desc, sizeof(p_elem->port_desc));
+ ret += sizeof(struct port);
+ buf += sizeof(struct port);
}
+ *len = ret;
return 0;
}
@@ -1297,6 +1290,7 @@
default:
return EINVAL;
}
+
return 0;
}
More information about the svn-soc-all
mailing list