From owner-svn-soc-all@freebsd.org Tue Jul 24 17:33:33 2018 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 444541051A97 for ; Tue, 24 Jul 2018 17:33:33 +0000 (UTC) (envelope-from sduo@FreeBSD.org) Received: from mxrelay.ysv.freebsd.org (mxrelay.ysv.freebsd.org [IPv6:2001:1900:2254:206a::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.ysv.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id CC57678715 for ; Tue, 24 Jul 2018 17:33:32 +0000 (UTC) (envelope-from sduo@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.ysv.freebsd.org (Postfix) with ESMTPS id 107CD192C6 for ; Tue, 24 Jul 2018 17:33:32 +0000 (UTC) (envelope-from sduo@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id w6OHXVmr058375 for ; Tue, 24 Jul 2018 17:33:31 GMT (envelope-from sduo@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id w6OHXVNI058366 for svn-soc-all@FreeBSD.org; Tue, 24 Jul 2018 17:33:31 GMT (envelope-from sduo@FreeBSD.org) Date: Tue, 24 Jul 2018 17:33:31 GMT Message-Id: <201807241733.w6OHXVNI058366@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to sduo@FreeBSD.org using -f From: sduo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r337270 - soc2018/sduo/head/sys/dev/vale_vlan MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.27 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 24 Jul 2018 17:33:33 -0000 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 +}