Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 24 Jul 2018 17:33:31 GMT
From:      sduo@FreeBSD.org
To:        svn-soc-all@FreeBSD.org
Subject:   socsvn commit: r337270 - soc2018/sduo/head/sys/dev/vale_vlan
Message-ID:  <201807241733.w6OHXVNI058366@socsvn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: sduo
Date: Tue Jul 24 17:33:28 2018
New Revision: 337270
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=337270

Log:
  Modified sys/dev/vale_vlan/vale_vlan.c to take advantage of the new nm_bdg_fwd fields (ft_head_space --> offsets).

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 Jul 19 13:37:18 2018	(r337269)
+++ soc2018/sduo/head/sys/dev/vale_vlan/vale_vlan.c	Tue Jul 24 17:33:28 2018	(r337270)
@@ -12,60 +12,82 @@
 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;
+		}
+
+		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_cur->ft_flags & NS_INDIRECT) {
+		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 +96,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 +119,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;
+	/* 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;
 
-			start_addr = buf;
-			dest_addr  = prev_buf + prev_buf_len - TAG_LENGTH;
-			*(uint32_t *)dest_addr = *(uint32_t *)start_addr;
-		}
-
-		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 +146,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;
@@ -237,6 +230,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 +240,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 +248,7 @@
 
 		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 +269,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);
 }
@@ -324,7 +323,7 @@
 	/* create bridge in exclusive mode */
 	get_tagging_bdg_name(tagging_bdg_name, sizeof(tagging_bdg_name),
 			     conf_name);
-	auth_token = netmap_bdg_create(tagging_bdg_name, &ret);
+	auth_token = netmap_vale_create(tagging_bdg_name, &ret);
 	if (auth_token == NULL || ret != 0) {
 		nm_prerr("Error %d during bridge %s creation\n", ret,
 			 tagging_bdg_name);
@@ -345,7 +344,7 @@
 		int ret2;
 		nm_prerr("Error %d during bridge %s regops()\n", ret,
 			 tagging_bdg_name);
-		ret2 = netmap_bdg_destroy(tagging_bdg_name,
+		ret2 = netmap_vale_destroy(tagging_bdg_name,
 					  conf->mod_bdg_auth_token);
 		if (ret2) {
 			/* cannot happen */
@@ -428,7 +427,7 @@
 
 	get_tagging_bdg_name(tagging_bdg_name, sizeof(tagging_bdg_name),
 			     conf_name);
-	ret = netmap_bdg_destroy(tagging_bdg_name, conf->mod_bdg_auth_token);
+	ret = netmap_vale_destroy(tagging_bdg_name, conf->mod_bdg_auth_token);
 	if (ret) {
 		/* cannot happen (?) */
 		nm_prerr("Error %d during bridge %s destroy(), "
@@ -506,7 +505,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 +592,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 +617,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);
@@ -653,7 +652,7 @@
 
 	if (conf->number_of_ports[vlan_id] == 0) {
 		/* we need to create a bridge in exclusive mode */
-		vlan_bdg_auth_token = netmap_bdg_create(vlan_bdg_name, &ret);
+		vlan_bdg_auth_token = netmap_vale_create(vlan_bdg_name, &ret);
 		if (vlan_bdg_auth_token == NULL || ret != 0) {
 			return ret;
 		}
@@ -726,7 +725,7 @@
 		 */
 		conf->vlan_bdg_auth_tokens[vlan_id] = NULL;
 		/* cannot fail */
-		netmap_bdg_destroy(vlan_bdg_name, vlan_bdg_auth_token);
+		netmap_vale_destroy(vlan_bdg_name, vlan_bdg_auth_token);
 	}
 
 	return ret;
@@ -905,7 +904,7 @@
 		goto l_attach_access_port_vlan_bdg;
 	}
 
-	ret = netmap_bdg_destroy(vlan_bdg_name, vlan_bdg_auth_token);
+	ret = netmap_vale_destroy(vlan_bdg_name, vlan_bdg_auth_token);
 	if (ret) {
 		/* cannot happen (?) */
 		goto l_create_access_port;
@@ -1309,4 +1308,4 @@
 		initialize_conf(&vlan_confs[i]);
 	}
 	nm_prinf("vale_vlan: module loaded\n");
-}
\ No newline at end of file
+}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201807241733.w6OHXVNI058366>