Showing posts with label Nexus. Show all posts
Showing posts with label Nexus. Show all posts

Thursday, 23 July 2026

Why BGP Maximum-Paths Wasn't the Problem: Fixing Uneven Port-Channel Traffic on Cisco Nexus and IOS

 If you've ever pulled up interface counters and seen one port-channel member carrying 70–80% of the traffic while its bundle-mate sits nearly idle, your first instinct is probably the same one we had: "BGP load balancing must be broken."

It usually isn't. Here's the case we worked through, why BGP was innocent from the start, and the actual fix.

TL;DR

  • Symptom: One port-channel member interface was carrying the majority of traffic; the other was underutilized.
  • First suspect: BGP maximum-paths — already configured correctly, and confirmed working via ECMP.
  • Real cause: The port-channel load-balancing algorithm (src-dst-ip enhanced) was hashing large, persistent flows onto the same physical link every time.
  • Fix: Move to src-dst-mixed-ip-port (or the NX-OS equivalent src-dst ip-l4port) to add Layer 4 entropy to the hash.
  • Caveat: If the imbalance is caused by a single "elephant flow," even L4 hashing won't split it — that needs a different tool entirely.

The Symptom

The environment was already running router bgp with maximum-paths 8 configured, so multiple equal-cost paths were expected to be installed and used. But interface counters told a different story — one member of the port-channel was consistently running hot while the other stayed quiet, day after day, regardless of overall traffic volume.

Router# show interface port-channel 10 | include rate
  5 minute input rate 812000000 bits/sec, 95000 packets/sec
  5 minute output rate 790000000 bits/sec, 92000 packets/sec

Router# show interface gigabitethernet 1/1 | include rate
  5 minute input rate 780000000 bits/sec, 91000 packets/sec

Router# show interface gigabitethernet 1/2 | include rate
  5 minute input rate 32000000 bits/sec, 4000 packets/sec

That's roughly a 96/4 split across two members of the same bundle — not something you'd expect from a healthy port-channel.

Ruling Out BGP First

Before touching anything on the switching side, we confirmed the routing layer was actually doing its job.

Router# show ip bgp summary
Router# show ip route 10.20.30.0
Routing entry for 10.20.30.0/24
  Known via "bgp 65001", distance 20, metric 0
  Routing Descriptor Blocks:
  * 192.168.1.1, from 192.168.1.1
      192.168.1.2, from 192.168.1.2

Two next-hops installed for the same prefix, exactly as maximum-paths 8 should produce when the paths are equal-cost. BGP ECMP was functioning correctly — routing decisions were being made across multiple paths, so it made no sense to keep chasing BGP config as the root cause.

That's the key thing to internalize: BGP ECMP and port-channel load balancing are two completely separate mechanisms operating at two different layers.

LayerMechanismDecides
Layer 3 (Routing)BGP maximum-paths / ECMPWhich path (next-hop) traffic takes
Layer 2 (Switching)Port-channel hash algorithmWhich physical member link within a bundle carries a given flow

Even with BGP perfectly distributing traffic across paths, each of those paths might egress through a port-channel — and it's entirely possible for the hashing algorithm on that port-channel to funnel most flows onto one member link regardless of what BGP is doing upstream.

Checking the Current Hashing Algorithm

Next step: find out what hash algorithm the port-channel was actually using.

On IOS / IOS-XE:

Router# show etherchannel load-balance
EtherChannel Load-Balancing Configuration:
        src-dst-ip

On Nexus (NX-OS):

Switch# show port-channel load-balance
Port Channel Load-Balancing Configuration:
System: src-dst ip

Both confirmed the same thing: the algorithm was using only Layer 3 information — source and destination IP address — to compute the hash and select a member link.

Why src-dst-ip Pins Big Flows to One Link

The hash is deterministic. Given the same source IP and destination IP, the algorithm produces the same result every single time, which means every packet in that flow is sent down the same physical link.

That's fine when you have many different flows between many different IP pairs — the hash spreads them out reasonably well. It falls apart when a small number of flows dominate the traffic, which is exactly what a database replication stream, a backup job, or a storage sync between two fixed IPs looks like: same source, same destination, forever — one hash result, one link, permanently.

This isn't a bug. Cisco's port-channel load balancing is intentionally flow-based, not packet-based, specifically to avoid packet reordering within a TCP session. The trade-off is that a big, long-lived flow can dominate a single member link even when the bundle as a whole has spare capacity.

The Fix: Add Layer 4 to the Hash

Switching from src-dst-ip to src-dst-mixed-ip-port pulls TCP/UDP source and destination port numbers into the hash calculation alongside the IP addresses.

IOS / IOS-XE:

Router(config)# port-channel load-balance src-dst-mixed-ip-port

NX-OS (Nexus):

Switch(config)# port-channel load-balance src-dst ip-l4port

Some Nexus platforms go a step further and support VLAN as an additional hash input for even more entropy:

Switch(config)# port-channel load-balance src-dst ip-l4port-vlan

With source/destination ports added, two different application sessions between the same pair of servers (say, a web server and a database server running several concurrent connections) will now very likely produce different hash results — and land on different physical links — instead of all piling onto whichever link the IP-only hash happened to pick.

In environments with many concurrent sessions between the same endpoints (application servers, load balancers, hypervisor clusters), this alone often meaningfully improves the balance.

Before You Make the Change

A few things worth knowing before you touch a production bundle:

  • It's generally non-disruptive on most Cisco platforms — you don't need to shut the port-channel.
  • Every existing flow gets re-hashed immediately. Expect a brief window of packet reordering as flows redistribute across members. It's usually transparent to TCP, but schedule the change for a maintenance window or low-traffic period if the environment is sensitive (VoIP, storage replication, etc.).
  • This is still flow-based hashing, just with more inputs. A single elephant flow — one enormous, sustained stream between one IP:port pair — will still be pinned to one physical link even after adding L4 information. Layer 4 hashing splits up multiple flows between the same hosts; it does not split a single flow.

If It's an Elephant Flow, Hashing Alone Won't Fix It

If, after the change, one link is still running noticeably hotter than the others, don't keep tweaking the hash algorithm — look for a dominant flow instead:

Router# show interface port-channel 10 | include rate
Switch# show flow monitor <name> cache

or pull top talkers from NetFlow/sFlow/telemetry. If you find one flow consuming most of the bandwidth, your real options are traffic engineering (splitting the application across multiple sessions/IPs if possible), platform-specific dynamic load balancing features (several Nexus platforms support Dynamic Load Balancing, which rebalances flows based on real-time link utilization rather than a static hash), or simply accepting that a single-flow workload isn't a great fit for port-channel-based scaling in the first place.

Verification Checklist

After changing the algorithm, give it a few hours under real traffic and check:

  • Port-channel member interface utilization (show interface … | include rate on each member)
  • Top bandwidth-consuming flows (NetFlow/sFlow/telemetry)
  • Interface error/discard counters (rule out anything unrelated masquerading as imbalance)
  • Application-level traffic distribution if you have flow visibility tools

If the split moves from something like 96/4 toward 55/45 or 60/40, the change did its job. If it barely moves, you're very likely looking at an elephant-flow scenario rather than a hashing-algorithm problem.

FAQ

Does changing the port-channel load-balancing algorithm cause an outage? No — on most Cisco IOS, IOS-XE, and NX-OS platforms this is a non-disruptive change. Existing flows get re-hashed and may briefly reorder, but the port-channel itself stays up.

Will src-dst-mixed-ip-port always produce perfectly even traffic distribution? No. It improves distribution when multiple flows exist between the same endpoints, but a single very large flow will still be pinned to one member link, since hashing is flow-based, not packet-based.

How do I check the current load-balancing algorithm on a Nexus switch? show port-channel load-balance on NX-OS. On IOS/IOS-XE, use show etherchannel load-balance.

Is BGP maximum-paths related to port-channel hashing at all? No — they operate at different layers. maximum-paths controls how many equal-cost paths BGP installs at Layer 3. Port-channel hashing controls which physical member link, at Layer 2, carries a given flow once it's already been routed onto that path.

What's the best load-balancing algorithm for Cisco port-channels in general? There isn't a universal "best" — it depends on traffic patterns. src-dst-mixed-ip-port (or NX-OS's ip-l4port) is a strong general-purpose default for environments with many concurrent sessions between the same hosts, since it adds the most useful entropy without added complexity.

Conclusion

BGP maximum-paths was never the issue in this case — it was correctly installing and using multiple equal-cost paths exactly as designed. The imbalance lived one layer down, in the port-channel's src-dst-ip hashing algorithm, which pins any given source/destination IP pair to a single physical link. Moving to src-dst-mixed-ip-port added Layer 4 awareness to the hash and meaningfully improved distribution — with the caveat that a genuine elephant flow needs a different fix entirely.

The broader lesson: when you see uneven link utilization on a bundle, don't assume the routing protocol is at fault. Check where the imbalance actually lives — Layer 3 path selection or Layer 2 hash distribution — before you start changing BGP configuration that may already be working exactly as intended.


Related Articles

If this was useful, these go deeper on the BGP and Cisco fundamentals that sit underneath this issue:

Tuesday, 10 June 2025

IP Helper address in NXOS

 In NX-OS, the command equivalent to Cisco IOS's ip helper-address for DHCP relay is ip dhcp relay address. Both commands serve the same purpose: forwarding DHCP requests from clients to a DHCP server located on a different subnet.

Friday, 24 January 2020

Jumbo frame configuration on Nexus


I have tried to explain the MTU configuration on the Nexus platform. MTU configuration varies based on the port type and hardware platform.

1. Layer 3 MTU Configurations

MTU configuraiton on L3 port is quite straight forward. Configuration is also same on all the platforms. We just need to give the MTU command on the interface configuration mode.

Configure MTU on a Switched Virtual Interface (SVI)
interface vlan 1
mtu 9216

Configure MTU on a Layer 3 Port
interface ethernet 1/1
no switchport
mtu 9216

2. Layer 2 MTU Configurations

MTU configuration on L2 port varies based on the hardware. On some platforms, we have to modify MTU under network-qos policy whereas on some MTU commands can be given under interface configuration mode.

2.1 Using QOS policy
On below hardware, jumbo frames can be configured using QOS policy.
Nexus 3000: Includes Nexus 3048, 3064, 3132Q, 3132Q-X, 3132Q-XL, 3172, and 3500 Series switches
Nexus 5000: All Nexus 5000 and 5500 Series switches
Nexus 6000: All Nexus 6000 Series switches

    Configuration: -
policy-map type network-qos jumbo
  class type network-qos class-default
          mtu 9216
system qos
  service-policy type network-qos jumbo

2.1 Per-Port MTU Configuration
On below hardware, jumbo frames can be configured directly under the interface.
           Nexus 3000: Includes Nexus 3132Q-V, 3164, 31108, 31128PQ, 3200 Series, and 36180YC-R switches
Nexus 7000: All Nexus 7000- and 7700 Series switches
Nexus 9000: All Nexus 9200 Series switches (includes 92xxx), 9300 Series switches (includes 93xxx), and 9500 Series switches

Nexus(config)#interface ethernet 1/1
Nexus(config-if)#mtu 9216




Sunday, 21 December 2014

OSPF configuration example on Nexus switches


Below is the OSPF configuration example on Nexus switches. Here OSPF is enable on the directly connected interface between 7K switches.



N7K-1:-

Step 1:- Enable OSPF feature


N7K-1(config)# feature ospf


Step 2:- Enable OSPF Process


N7K-1(config)# router ospf 10  --<<<< OSPF process ID
N7K-1(config-router)# router-id 10.1.1.1


Step 3:- Enable ospf on particular interface


N7K-12-1(config-router)# int Eth1/1
N7K-2(config-if)#ip address 10.1.1.1 255.255.255.252
N7K-12-1(config-if)# ip router ospf 100 area 0


N7K-2:-

Step 4 :- Enable OSPF feature


N7K-2(config)# feature ospf


Step 5:- Enable OSPF Process


N7K-2(config)# router ospf 100  --<<<< OSPF process ID
N7K-2(config-router)# router-id 10.1.1.2


Step 6:- Enable ospf on particular interface.


N7K-2(config)# int Eth1/1
N7K-2(config-if)#ip address 10.1.1.2 255.255.255.252
N7K-2(config-if)# ip router ospf 100 area 0


Step 7 :-  Optional- Below command can be used if we want to disable the neighborship on particular interface.


N7K-1(config)# int Eth1/1
N7K-1(config-if)# ip ospf 100 passive-interface ---< To disable neighborship but still advertise the network

N7K-1(config-if)# ip ospf network point-to-point --<< To change the network type

Verification :-

A. Show ip ospf neighbor

N7K-1# sh ip ospf neighbors
 OSPF Process ID 100 VRF default
 Total number of neighbors: 1
 Neighbor ID     Pri State       Up Time  Address      Interface
 100.1.1.2         1 FULL/ -     00:00:08 100.1.1.2       Eth1/1

EIGRP configuration example on Nexus 7K switches


Below is the EIGRP configuration example on Nexus switches. Here EIGRP is enable on the directly connected interface between 7K switches.



N7K-1:-

Step1 :- Enable EIGRP feature


N7K-1(config)# feature eigrp


Step2:- Enable EIGRP Process


N7K-1(config)# router eigrp 100
N7K-1(config-router)# router-id 10.1.1.1


Step3:- Enable eigrp on particular interface


N7K-12-1(config-router)# int Eth1/1
N7K-2(config-if)#ip address 10.1.1.1 255.255.255.252
N7K-12-1(config-if)# ip router eigrp 100


N7K-2:-

Step4 :- Enable EIGRP feature


N7K-2(config)# feature eigrp


Step5:- Enable EIGRP Process


N7K-2(config)# router eigrp 100
N7K-2(config-router)# router-id 10.1.1.2


Step6:- Enable EIGRP on particular interface.


N7K-2(config)# int Eth1/1
N7K-2(config-if)#ip address 10.1.1.2 255.255.255.252
N7K-2(config-if)# ip router eigrp 100


Step7 :-  Optional- Below command can be used if we want to disable the neighborship on particular interface.


N7K-1(config)# int Eth1/1
N7K-1(config-if)# ip passive-interface eigrp 100 ---< To disable neighborship but Still advertise the network

N7K-1(config-if)# ip eigrp 100 shutdown  --<< To disable EIGRP on interface. Both hello packet and advertisement will be stopped.



Verification :-

A.Show ip eigrp neighbor


N7K-1(config-if)# sh ip eigrp neighbors
IP-EIGRP neighbors for process 100 VRF default
H   Address                 Interface       Hold  Uptime  SRTT   RTO  Q  Seq
                                            (sec)         (ms)       Cnt Num
0   10.1.1.2               Eth1/1         14   00:00:42  9    200   0   3


   B.Show ip route


N7K-5-1# sh ip route
IP Route Table for VRF "default"
'*' denotes best ucast next-hop
'**' denotes best mcast next-hop
'[x/y]' denotes [preference/metric]

10.1.1.0/30, ubest/mbest: 1/0, attached
    *via 10.1.1.2, Eth1/1, [0/0], 00:20:41, direct
10.1.1.2/32, ubest/mbest: 1/0, attached
    *via 10.1.1.2, Eth1/1, [0/0], 00:20:41, local
200.1.1.0/24, ubest/mbest: 1/0
    *via 10.1.1.1, Eth1/1, [90/3072], 00:00:09, eigrp-100, internal





Saturday, 6 December 2014

Nexus - HSRP Configuration example


Below is the HSRP configuration example.




Below is the HSRP configuration example.

N7K-1:-

feature hsrp
feature interface-vlan

vlan 100

int eth1/1
switchport mode trunk
 no shut

int vlan 100
ip address 100.1.1.2/24
hsrp 100
ip 100.1.1.1
preempt
priority 105
 no shut

N7K-2:-

feature hsrp
feature interface-vlan

vlan 100

int eth1/1
switchport mode trunk
 no shut

int vlan 100
ip address 100.1.1.3/24
hsrp 100
ip 100.1.1.1
preempt
no shut

Verification:-

1.  show hsrp brief

N7K-1#show hsrp brief
P indicates configured to preempt.
|
Interface Grp Prio P State Active addr Standby addr Group addr
Vlan100   100 105  P Active    local  100.1.1.3 100.1.1.1


2. show hsrp interface vlan 100

N7K-1#show hsrp interface vlan 100
Vlan100 - Group 100 (HSRP-V1) (IPv4)
  Local state is Active, priority 105 (Cfged 105), may preempt       Forwarding threshold(for vPC), lower: 1 upper: 105
  Hellotime 3 sec, holdtime 10 sec
  Next hello sent in 0.821000 sec(s)
  Virtual IP address is 100.1.1.1 (Cfged)
  Active router is local
  Standby router is 100.1.1.3 , priority 100 expires in 0.411000 sec(s)
  Authentication text "cisco"
  Virtual mac address is 0000.0c07.ac64 (Default MAC)
  1 state changes, last state change 00:04:11
  IP redundancy name is hsrp-Vlan100-100 (default)




Friday, 5 December 2014

VPC+ configuration example

Below is the VPC+ configuration example.

VPC+ is configured between N5k-1 and N5k-2 where fabric path is configured on the VPC peer-link. We assume that Teaming is properly configured on the server end and hence only switch side configuration is demonstrated here.





N7K-1:-

Install feature-set fabricpath  //--<<<< It must be executed in Default or Admin VDC //
feature-set fabricpath
feature lacp

fabricpath switch-id 71  //--<< To configure Static switch-id otherwise it will be dynamically assigned//

vlan 100
  mode fabricpath

interface Ethernet1/1
  switchport mode fabricpath

interface Ethernet1/3
  switchport mode fabricpath

interface Ethernet1/4
  switchport mode fabricpath


N7K-2 :-

Install feature-set fabricpath
feature-set fabricpath
feature lacp

fabricpath switch-id 72

vlan 100
  mode fabricpath

interface Ethernet1/1
  switchport mode fabricpath

interface Ethernet1/3
  switchport mode fabricpath

interface Ethernet1/4
  switchport mode fabricpath


N5K-1 :-

Install feature-set fabricpath
feature-set fabricpath
feature Lacp
feature vpc

fabricpath switch-id 51

vpc domain 100
 peer-keepalive destination 10.1.1.52
  fabricpath switch-id 55  //----<<<<<<<<<<<< Must be configured for VPC+ //

vlan 100
  mode fabricpath

interface Ethernet1/1
  Channel-group 1 mode active
  switchport mode fabricpath

interface Ethernet1/2
  Channel-group 1 mode active
  switchport mode fabricpath

interface port-channel1
  switchport mode fabricpath
  VPC peer-link

interface Ethernet1/3
  switchport mode fabricpath

interface Ethernet1/4
  switchport mode fabricpath

interface Ethernet1/5
Channel-group 2000 mode active
  switchport mode trunk

int po2000
switchport mode trunk
vpc 2000
no shut

N5K-2 :-

install feature-set fabricpath
feature-set fabricpath
feature lacp
feature vpc

fabricpath switch-id 52

vlan 100
mode fabricpath

vpc domain 100
 peer-keepalive destination 10.1.1.51
  fabricpath switch-id 55

Note:- If you missed to configure sub switch-id under VPC domain then VPC peer-link will remain down.

interface Ethernet1/1
Channel-group 1 mode active
 switchport mode fabricpath

interface Ethernet1/2
Channel-group 1 mode active
switchport mode fabricpath

interface port-channel1
  switchport mode fabricpath
  VPC peer-link

interface Ethernet1/3
switchport mode fabricpath

interface Ethernet1/4
  switchport mode fabricpath

interface Ethernet1/5
 Channel-group 2000 mode active
  switchport mode trunk

int po2000
switchport mode trunk
vpc 2000
no shut


Verification:-  

1. Show fabricpath switch-id

N7K-1# show fabricpath switch-id
                        FABRICPATH SWITCH-ID TABLE
Legend: '*' - this system
=========================================================================
SWITCH-ID      SYSTEM-ID       FLAGS         STATE    STATIC  EMULATED
----------+----------------+------------+-----------+--------------------
51          0005.73bd.fabc    Primary     Confirmed     Yes     No
52          0005.73bf.337c    Primary     Confirmed     Yes     No
55          0005.73bd.fabc    Primary     Confirmed     No      Yes
55          0005.73bf.337c    Primary     Confirmed     No      Yes
*71          0026.980d.4143    Primary     Confirmed    Yes     No
72          0026.980d.3c43    Primary     Confirmed     Yes     No


2. Show fabricpath isis adjacency


N7K-1# show fabricpath isis adjacency
Fabricpath IS-IS domain: default Fabricpath IS-IS adjacency database:
System ID       SNPA            Level  State  Hold Time  Interface
N5K-1        N/A             1      UP     00:00:28   Ethernet1/3
N5K-2        N/A             1      UP     00:00:26   Ethernet1/4
N7K-2         N/A             1      UP     00:00:28   Ethernet1/1


3. Show vpc brief


N5K -2(config-if)# show vpc brief
Legend:
                (*) - local vPC is down, forwarding via vPC peer-link

vPC domain id                   : 100
vPC+ switch id                  : 55
Peer status                     : peer adjacency formed ok
vPC keep-alive status           : peer is alive
vPC fabricpath status           : peer is reachable through fabricpath---<<<<<<
Configuration consistency status: success
Per-vlan consistency status     : success
Type-2 consistency status       : success
vPC role                        : secondary
Number of vPCs configured       : 1
Peer Gateway                    : Disabled
Dual-active excluded VLANs      : -
Graceful Consistency Check      : Enabled

vPC Peer-link status
---------------------------------------------------------------------
id   Port   Status Active vlans
--   ----   ------ --------------------------------------------------
1    Po1    up     100

vPC status
---------------------------------------------------------------------------
id     Port        Status Consistency Reason       Active vlans vPC+ Attrib
--     ----------  ------ ----------- ------       ------------ -----------
2000     Po2000        up     success     success      100          DF: Partial