VLAN manipulation/translation on Juniper MX series routers

The MX series routers are truly excellent. As well as being used for routing, they can also be used for switching. Switches do routing, so why not the other way around… right?

A basic switching setup on an MX is a VLAN bridge. Take the following config. It is akin to setting 2 802.1Q trunk ports on a switch, both in VLAN 66:

  1. interfaces {
  2. ge-1/0/4 {
  3. flexible-vlan-tagging;
  4. encapsulation flexible-ethernet-services;
  5. unit 66 {
  6. encapsulation vlan-bridge;
  7. vlan-id 66;
  8. }
  9. }
  10. ge-1/1/7 {
  11. flexible-vlan-tagging;
  12. encapsulation flexible-ethernet-services;
  13. unit 66 {
  14. encapsulation vlan-bridge;
  15. vlan-id 66;
  16. }
  17. }
  18. }
  19. bridge-domains {
  20. my-bridge {
  21. domain-type bridge;
  22. vlan-id 66;
  23. interface ge-1/0/4.66;
  24. interface ge-1/1/7.66;
  25. }
  26. }

Here we have 2 interfaces, both with a unit that matches traffic tagged for VLAN 66. The bridge domain sends layer 2 traffic between these two interfaces, as if it were a switch.

Bridge domains on the MX inherently do what is called VLAN Normalization/Translation. When a packet enters an interface, its VLAN is normalized to that of the bridge domain. When a packet leaves an interface, its VLAN is normalized to that of the exiting interface. The above example has the same VLAN on both interfaces and the bridge domain, so let’s look at a different example:

  1. interfaces {
  2. ge-1/0/4 {
  3. flexible-vlan-tagging;
  4. encapsulation flexible-ethernet-services;
  5. unit 55 {
  6. encapsulation vlan-bridge;
  7. vlan-id 55;
  8. }
  9. }
  10. ge-1/1/7 {
  11. flexible-vlan-tagging;
  12. encapsulation flexible-ethernet-services;
  13. unit 66 {
  14. encapsulation vlan-bridge;
  15. vlan-id 66;
  16. }
  17. }
  18. }
  19. bridge-domains {
  20. my-bridge {
  21. domain-type bridge;
  22. vlan-id 43;
  23. interface ge-1/0/4.55;
  24. interface ge-1/1/7.66;
  25. }
  26. }

In this example, when a packet tagged VLAN 55 enters on ge-1/0/4, its VLAN tag is swapped for 43 because that is the VLAN ID of the bridge. When the same packet leaves on ge-1/1/7, its VLAN tag is swapped again for 66 because that is the VLAN ID of the exiting interface.

As you can probably see, this is a silly example… the VLAN 43 is pointless here but it gives you an idea of what happens when packets traverse the bridge.

You can see this behavior when you do “show interfaces”:

  1. mx10> show interfaces ge-1/0/4.55
  2. Logical interface ge-1/0/4.55 (Index 346) (SNMP ifIndex 612)
  3. Flags: SNMP-Traps 0x0 VLAN-Tag [ 0x8100.55 ] In(swap .43) Out(swap .55) Encapsulation: VLAN-Bridge
  4.  
  5. mx10> show interfaces ge-1/1/7.66
  6. Logical interface ge-1/1/7.66 (Index 344) (SNMP ifIndex 611)
  7. Flags: SNMP-Traps 0x0 VLAN-Tag [ 0x8100.66 ] In(swap .43) Out(swap .66) Encapsulation: VLAN-Bridge

The key bit is the Flags line. You can see that input packets are swapped with VLAN 43 and output packets are swapped with the VLAN of the interface.

The above example shows you VLAN translation. In reality, you’d probably set the vlan-id of the bridge-domain to one of your interface VLANs or perhaps “none”. In the case of setting it to one of your VLANs, you’d see no work done on packets coming into/leaving the interface with the same VLAN ID and a swap for both In/Out on the other interface. In the case of “none”, the VLAN tag would be removed as a packet comes in and a new tag would be added when the packet leaves. This removal is called a “pop” and the addition as “push”.

Another good example of the usage of this is to convert a double tagged (Q-in-Q) packet to a single tagged one. You might have a provider who is using Q-in-Q and you want to remove their VLAN (the S-VLAN) and use only your VLAN (the C-VLAN) on devices which are on the “other side” of your MX. Here’s an example of that:

  1. interfaces {
  2. ge-1/0/0 {
  3. flexible-vlan-tagging;
  4. encapsulation flexible-ethernet-services;
  5. unit 601 {
  6. encapsulation vlan-bridge;
  7. vlan-id 601;
  8. }
  9. }
  10. ge-1/1/3 {
  11. flexible-vlan-tagging;
  12. encapsulation flexible-ethernet-services;
  13. unit 601 {
  14. encapsulation vlan-bridge;
  15. vlan-tags outer 255 inner 601;
  16. }
  17. }
  18. }
  19. bridge-domain {
  20. vlan-601 {
  21. domain-type bridge;
  22. vlan-id 601;
  23. interface ge-1/0/0.601;
  24. interface ge-1/1/3.601;
  25. }
  26. }

So here, we have a single tagged and a double tagged interface. The assumption is that the single tagged interface is facing our equipment (e.g. an SRX) and the double tagged interface is facing the provider. When double tagged packets from the provider enter on ge-1/1/3, the outer VLAN is removed (pop) because the vlan-id of the bridge domain is 601 – the same as the inner vlan-id. When packets leave on ge-1/0/0, nothing is done as the VLAN is already 601.

In the opposite direction, single tagged packets enter on ge-1/0/0. Nothing is done to them because the vlan-id already matches that of the bridge. When packets leave on ge-1/1/3, the VLAN 255 is added (push). Here’s what the “show interfaces” says:

  1. mx10> show interfaces ge-1/0/0.601
  2. Logical interface ge-1/0/0.601 (Index 363) (SNMP ifIndex 590)
  3. Flags: SNMP-Traps 0x0 VLAN-Tag [ 0x8100.601 ] Encapsulation: VLAN-Bridge
  4.  
  5. mx10> show interfaces ge-1/1/3.601
  6. Logical interface ge-1/1/3.601 (Index 374) (SNMP ifIndex 589)
  7. Flags: SNMP-Traps 0x0 VLAN-Tag [ 0x8100.255 0x8100.601 ] In(pop) Out(push 0x8100.255) Encapsulation: VLAN-Bridge

See the push/pop on the double tagged interface and nothing on the single tagged interface.

If you set no vlan-id on the bridge-domain… you are then allowed to define input-vlan-map and output-vlan-map on the logical interfaces. This allows you to customize exactly what happens in ingress and egress packets, rather than taking the default behavior as explained above.