VLAN-tagging
PATCH v2 1/1 VLAN-tagging
Hi,
I didn't have much time the last few days, but as I'll be without Internet access Tuesday through Friday I wanted to push out what I've come up with so far. I've attached the diff between my first patch-series and this posting. If people would prefer to see the individual patches in their reworked form, just say so and I'll post those in the future. For now, they're available on the feat_vlan/r12 tag at
git://fsmi-dev.fsmi.uni-karlsruhe.de/openvpn.git
or
http://opensource.fsmi.uni-karlsruhe.de/cgi-bin/gitweb.cgi?p=openvpn.git
The changes:
* Fixed the valid VID range to be from 1-0xFFFE to 1-4094 (0xFFE). Changed the VID field mask to 0x0FFF. (If someone can explain a use-case for VID=0 to me, I might allow that too.)
* "--vlan-tag" was renamed to "--vlan-pvid" and is now also valid in global context (where it configures the PVID for the tap device).
* The boolean "--vlan-tagging" option was replaced by "--vlan-accept raw | tagged | untagged | all". "raw" corresponds to the old "no --vlan-tagging" and "tagged" corresponds to the old "--vlan-tagging". "untagged" accepts only untagged (or priority tagged) packets on the tap device. It assumes they belong to the VID set by the global "--vlan-pvid". "all" accepts VLAN-tagged and untagged packets and handles them the way the "tagged" and "untagged" modes would.
I'm planning to reintroduce the previous on/off switch and just supplement that with the new "--vlan-accept mode" (which would then only allow you to choose between 'tagged | untagged | all'. The thinking behind the two separate switches would be, that "raw" mode makes OpenVPN behave different on a global level, while "tagged", "untagged" and "all" only change the behaviour regarding the tap device. (In theory, "--vlan-accept" could be made into an instance option, allowing clients to send tagged packets, etc..)
* Compile-time switch ("--disable-vlan-tagging" / "--enable-vlan-tagging") to enable/disable the VLAN-tagging feature Default is enabled. When disabled, OpenVPN should behave the same way as in "--vlan-accept raw" mode.
* Added a first attempt at documentation to openvpn.8
* VLAN-tagged packets coming in via the client links are dropped if "--vlan-accept" is in non-"raw" mode. (Priority-tagged packets aren't affected.)
* VLAN-tagged packets coming in through tap, that contain priority information have their priority information preserved and get sent on as priority-tagged packets. I'm not sure whether this is a good idea though. The decision is based on whether the PCP-field is non-zero. I haven't been able to find out what the standard has to say on the matter or what switches typically do in that situation.
Linux allows you to do fixed egress and ingress priority tagging (or more precise: mapping from the TOS field), so that would imply changing the IP-header's TOS field.
Again, the patches have only received light testing so far. I've tested all accept modes though, so there hopefully shouldn't be any obvious brown-paper bag bugs. More thorough testing will hopefully start next week.
BTW, I'll add Signed-Off-By-lines as soon as I'm a bit more confident in the patches. (And ... assuming I don't forget adding the flag, like I did this time. :) )
If you haven't had a thorough look at my previous patch-set yet, I strongly suggest you go through my individual patches from my git tree, as they're IMHO easier to understand one by one.
Cheers
Fabian
configure.ac +12 -0
@@ -212,6 +212,12 @@ AC_ARG_ENABLE(selinux, [SELINUX="yes"] ) +AC_ARG_ENABLE(vlan-tagging, + [ --disable-vlan-tagging Disable support for VLAN tagging/untagging], + [VLAN_TAGGING="$enableval"], + [VLAN_TAGGING="yes"] +) + AC_ARG_WITH(ssl-headers, [ --with-ssl-headers=DIR Crypto/SSL Include files location], [CS_HDR_DIR="$withval"]
@@ -886,6 +892,12 @@ if test "$SELINUX" = "yes"; then ) fi +dnl enable --vlan-tagging +if test "$VLAN_TAGGING" = "yes"; then + AC_DEFINE(ENABLE_VLAN_TAGGING, 1, [Enable VLAN tagging/untagging]) +fi + + TAP_ID="PRODUCT_TAP_ID" TAP_WIN32_MIN_MAJOR="PRODUCT_TAP_WIN32_MIN_MAJOR" TAP_WIN32_MIN_MINOR="PRODUCT_TAP_WIN32_MIN_MINOR"
errlevel.h +2 -0
@@ -144,6 +144,8 @@#define D_PF_DROPPED_BCAST LOGLEV(7, 71, M_DEBUG)/* packet filter dropped a broadcast packet */ #define D_PF_DEBUG LOGLEV(7, 72, M_DEBUG)/* packet filter debugging, must also define PF_DEBUG in pf.h */ +#define D_VLAN_DEBUG LOGLEV(7, 72, M_DEBUG)/* show VLAN tagging/untagging debug info */ +#define D_HANDSHAKE_VERBOSE LOGLEV(8, 70, M_DEBUG)/* show detailed description of each handshake */ #define D_TLS_DEBUG_MED LOGLEV(8, 70, M_DEBUG)/* limited info from tls_session routines */ #define D_INTERVAL LOGLEV(8, 70, M_DEBUG)/* show interval.h debugging info */
mroute.c +21 -11
@@ -164,6 +164,21 @@ mroute_extract_addr_ipv4 (struct mroute_addr *src,return ret; } +static void mroute_copy_ether_to_addr (struct mroute_addr *maddr, +const uint8_t *eth_addr, +int16_t vid) +{ + maddr->type =MR_ADDR_ETHER ; + maddr->netbits =0 ; +memcpy (maddr->addr, eth_addr,6 ); +#ifdef ENABLE_VLAN_TAGGING + maddr->len =8 ; +memcpy (maddr->addr +6 , &vid,2 ); +#else + maddr->len =6 ; +#endif +} + unsigned int mroute_extract_addr_ether (struct mroute_addr *src, struct mroute_addr *dest,
@@ -178,19 +193,11 @@ mroute_extract_addr_ether (struct mroute_addr *src,const struct openvpn_ethhdr *eth = (const struct openvpn_ethhdr *)BPTR (buf);if (src) { - src->type =MR_ADDR_ETHER ; - src->netbits =0 ; - src->len =8 ; -memcpy (src->addr, eth->source,6 ); -memcpy (src->addr +6 , &vid,2 ); +mroute_copy_ether_to_addr (src, eth->source, vid); }if (dest) { - dest->type =MR_ADDR_ETHER ; - dest->netbits =0 ; - dest->len =8 ; -memcpy (dest->addr, eth->dest,6 ); -memcpy (dest->addr +6 , &vid,2 ); +mroute_copy_ether_to_addr (dest, eth->dest, vid);/* ethernet broadcast/multicast packet? */ if (is_mac_mcast_addr (eth->dest))
@@ -206,7 +213,8 @@ mroute_extract_addr_ether (struct mroute_addr *src,if (buf_advance (&b,sizeof (struct openvpn_ethhdr ))) {uint16_t proto =ntohs (eth->proto); -if (proto ==OPENVPN_ETH_P_8021Q ) +if (proto ==OPENVPN_ETH_P_8021Q && +BLEN (buf) >= (int )sizeof (struct openvpn_8021qhdr )) {const struct openvpn_8021qhdr *tag = (const struct openvpn_8021qhdr *)BPTR (buf); proto =ntohs (tag->proto);
@@ -314,7 +322,9 @@ mroute_addr_print_ex (const struct mroute_addr *ma, {case MR_ADDR_ETHER :buf_printf (&out,"%s" ,format_hex_ex (ma->addr,6 ,0 ,1 ,":" , gc)); +#ifdef ENABLE_VLAN_TAGGING buf_printf (&out,"@%d" , *(int16_t *)(ma->addr +6 )); +#endif break ;case MR_ADDR_IPV4 : {
multi.c +170 -57
313 lines not on this page · raw message
multi.h +21 -3
@@ -405,7 +405,9 @@ multi_get_timeout (struct multi_context *m, struct timeval *dest)static inline bool multi_process_outgoing_tun (struct multi_context *m,const unsigned int mpp_flags) { -void multi_prepend_vlan_identifier (struct multi_instance *mi,struct buffer *buf); +#ifdef ENABLE_VLAN_TAGGING +void multi_prepend_vlan_tag (const struct context *c,struct buffer *buf); +#endif struct multi_instance *mi = m->pending;bool ret = true;
@@ -416,10 +418,26 @@ multi_process_outgoing_tun (struct multi_context *m, const unsigned int mpp_flag mi->context.c2.to_tun.len);#endif set_prefix (mi); -if (mi->context.options.vlan_tag) +#ifdef ENABLE_VLAN_TAGGING +if (m->top.options.vlan_accept ==VAF_ONLY_UNTAGGED_OR_PRIORITY ) { -multi_prepend_vlan_identifier (mi, &mi->context.c2.to_tun); +/* Packets aren't tagged on the tap device. */ + +if (m->top.options.vlan_pvid != mi->context.options.vlan_pvid) + { +/* Packet is coming from the wrong VID, drop it. */ + mi->context.c2.to_tun.len =0 ; + } } +else if (m->top.options.vlan_accept ==VAF_ONLY_VLAN_TAGGED || + (m->top.options.vlan_accept ==VAF_ALL && + m->top.options.vlan_pvid != mi->context.options.vlan_pvid)) + { +/* Packets need to be tagged. Either because all packets are tagged or +because the vid matches the port's pvid. */ +multi_prepend_vlan_tag (&mi->context, &mi->context.c2.to_tun); + } +#endif process_outgoing_tun (&mi->context); ret =multi_process_post (m, mi, mpp_flags);clear_prefix ();
openvpn.8 +81 -0
87 lines not on this page · raw message
options.c +72 -26
167 lines not on this page · raw message
options.h +14 -2
@@ -126,6 +126,16 @@ struct remote_list#endif +#ifdef ENABLE_VLAN_TAGGING +enum vlan_acceptable_frames +{ +VAF_RAW =0 , +VAF_ONLY_VLAN_TAGGED , +VAF_ONLY_UNTAGGED_OR_PRIORITY , +VAF_ALL , +}; +#endif +/* Command line options */ struct options {
@@ -510,8 +520,10 @@ struct optionsint route_method;#endif -bool vlan_tagging; -int vlan_tag; +#ifdef ENABLE_VLAN_TAGGING +enum vlan_acceptable_frames vlan_accept; +int vlan_pvid; +#endif };#define streq (x, y) (!strcmp((x), (y)))
proto.h +45 -9
85 lines not on this page · raw message
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Quoted 68 lines · Fabian Knittel
Hi,
I didn't have much time the last few days, but as I'll be without Internet access Tuesday through Friday I wanted to push out what I've come up with so far. I've attached the diff between my first patch-series and this posting. If people would prefer to see the individual patches in their reworked form, just say so and I'll post those in the future. For now, they're available on the feat_vlan/r12 tag at
git://fsmi-dev.fsmi.uni-karlsruhe.de/openvpn.gitor
http://opensource.fsmi.uni-karlsruhe.de/cgi-bin/gitweb.cgi?p=openvpn.gitThe changes:
* Fixed the valid VID range to be from 1-0xFFFE to 1-4094 (
0xFFE). Changed the VID field mask to0x0FFF. (If someone can explain a use-case for VID=0 to me, I might allow that too.)* "--vlan-tag" was renamed to "--vlan-pvid" and is now also valid in global context (where it configures the PVID for the tap device).
* The boolean "--vlan-tagging" option was replaced by "--vlan-accept raw | tagged | untagged | all". "raw" corresponds to the old "no --vlan-tagging" and "tagged" corresponds to the old "--vlan-tagging". "untagged" accepts only untagged (or priority tagged) packets on the tap device. It assumes they belong to the VID set by the global "--vlan-pvid". "all" accepts VLAN-tagged and untagged packets and handles them the way the "tagged" and "untagged" modes would.
I'm planning to reintroduce the previous on/off switch and just supplement that with the new "--vlan-accept mode" (which would then only allow you to choose between 'tagged | untagged | all'. The thinking behind the two separate switches would be, that "raw" mode makes OpenVPN behave different on a global level, while "tagged", "untagged" and "all" only change the behaviour regarding the tap device. (In theory, "--vlan-accept" could be made into an instance option, allowing clients to send tagged packets, etc..)
* Compile-time switch ("--disable-vlan-tagging" / "--enable-vlan-tagging") to enable/disable the VLAN-tagging feature Default is enabled. When disabled, OpenVPN should behave the same way as in "--vlan-accept raw" mode.
* Added a first attempt at documentation to openvpn.8
* VLAN-tagged packets coming in via the client links are dropped if "--vlan-accept" is in non-"raw" mode. (Priority-tagged packets aren't affected.)
* VLAN-tagged packets coming in through tap, that contain priority information have their priority information preserved and get sent on as priority-tagged packets. I'm not sure whether this is a good idea though. The decision is based on whether the PCP-field is non-zero. I haven't been able to find out what the standard has to say on the matter or what switches typically do in that situation.
Linux allows you to do fixed egress and ingress priority tagging (or more precise: mapping from the TOS field), so that would imply changing the IP-header's TOS field.
Again, the patches have only received light testing so far. I've tested all accept modes though, so there hopefully shouldn't be any obvious brown-paper bag bugs. More thorough testing will hopefully start next week.
Quoted 8 lines
BTW, I'll add Signed-Off-By-lines as soon as I'm a bit more confident in the patches. (And ... assuming I don't forget adding the flag, like I did this time. :) )
If you haven't had a thorough look at my previous patch-set yet, I strongly suggest you go through my individual patches from my git tree, as they're IMHO easier to understand one by one.
I've pulled down your git tree (feat_vlan branch), and published it as feat_vlan_tagging in the openvpn-testing.git tree. Currently it has not been merged into allmerged, before it gets a better review of the latest changes. But I'll pull in changes from your tree on request. Please provide such a summary as above on pull requests, to get more information about what's being pulled in.
kind regards,
David Sommerseth
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/
iEYEARECAAYFAku+LjAACgkQDC186MBRfrr6TgCeJAVtNUUG88PpW9MHoN0D6kSU u88AoJSTDabXdSJz6cr5nT0eJk9uht+M
=81KC
-----END PGP SIGNATURE-----