@@ -622,9 +622,9 @@ static int vxlan_fdb_append(struct vxlan_fdb *f,
622
622
return 1 ;
623
623
}
624
624
625
- static bool vxlan_parse_gpe_proto (struct vxlanhdr * hdr , __be16 * protocol )
625
+ static bool vxlan_parse_gpe_proto (const struct vxlanhdr * hdr , __be16 * protocol )
626
626
{
627
- struct vxlanhdr_gpe * gpe = (struct vxlanhdr_gpe * )hdr ;
627
+ const struct vxlanhdr_gpe * gpe = (const struct vxlanhdr_gpe * )hdr ;
628
628
629
629
/* Need to have Next Protocol set for interfaces in GPE mode. */
630
630
if (!gpe -> np_applied )
@@ -1554,41 +1554,38 @@ static void vxlan_sock_release(struct vxlan_dev *vxlan)
1554
1554
#endif
1555
1555
}
1556
1556
1557
- static enum skb_drop_reason vxlan_remcsum (struct vxlanhdr * unparsed ,
1558
- struct sk_buff * skb ,
1559
- u32 vxflags )
1557
+ static enum skb_drop_reason vxlan_remcsum (struct sk_buff * skb , u32 vxflags )
1560
1558
{
1559
+ const struct vxlanhdr * vh = vxlan_hdr (skb );
1561
1560
enum skb_drop_reason reason ;
1562
1561
size_t start , offset ;
1563
1562
1564
- if (!(unparsed -> vx_flags & VXLAN_HF_RCO ) || skb -> remcsum_offload )
1565
- goto out ;
1563
+ if (!(vh -> vx_flags & VXLAN_HF_RCO ) || skb -> remcsum_offload )
1564
+ return SKB_NOT_DROPPED_YET ;
1566
1565
1567
- start = vxlan_rco_start (unparsed -> vx_vni );
1568
- offset = start + vxlan_rco_offset (unparsed -> vx_vni );
1566
+ start = vxlan_rco_start (vh -> vx_vni );
1567
+ offset = start + vxlan_rco_offset (vh -> vx_vni );
1569
1568
1570
1569
reason = pskb_may_pull_reason (skb , offset + sizeof (u16 ));
1571
1570
if (reason )
1572
1571
return reason ;
1573
1572
1574
1573
skb_remcsum_process (skb , (void * )(vxlan_hdr (skb ) + 1 ), start , offset ,
1575
1574
!!(vxflags & VXLAN_F_REMCSUM_NOPARTIAL ));
1576
- out :
1577
- unparsed -> vx_flags &= ~VXLAN_HF_RCO ;
1578
- unparsed -> vx_vni &= VXLAN_VNI_MASK ;
1579
-
1580
1575
return SKB_NOT_DROPPED_YET ;
1581
1576
}
1582
1577
1583
- static void vxlan_parse_gbp_hdr (struct vxlanhdr * unparsed ,
1584
- struct sk_buff * skb , u32 vxflags ,
1578
+ static void vxlan_parse_gbp_hdr (struct sk_buff * skb , u32 vxflags ,
1585
1579
struct vxlan_metadata * md )
1586
1580
{
1587
- struct vxlanhdr_gbp * gbp = (struct vxlanhdr_gbp * )unparsed ;
1581
+ const struct vxlanhdr * vh = vxlan_hdr (skb );
1582
+ const struct vxlanhdr_gbp * gbp ;
1588
1583
struct metadata_dst * tun_dst ;
1589
1584
1590
- if (!(unparsed -> vx_flags & VXLAN_HF_GBP ))
1591
- goto out ;
1585
+ gbp = (const struct vxlanhdr_gbp * )vh ;
1586
+
1587
+ if (!(vh -> vx_flags & VXLAN_HF_GBP ))
1588
+ return ;
1592
1589
1593
1590
md -> gbp = ntohs (gbp -> policy_id );
1594
1591
@@ -1607,8 +1604,6 @@ static void vxlan_parse_gbp_hdr(struct vxlanhdr *unparsed,
1607
1604
/* In flow-based mode, GBP is carried in dst_metadata */
1608
1605
if (!(vxflags & VXLAN_F_COLLECT_METADATA ))
1609
1606
skb -> mark = md -> gbp ;
1610
- out :
1611
- unparsed -> vx_flags &= ~VXLAN_GBP_USED_BITS ;
1612
1607
}
1613
1608
1614
1609
static enum skb_drop_reason vxlan_set_mac (struct vxlan_dev * vxlan ,
@@ -1672,9 +1667,9 @@ static bool vxlan_ecn_decapsulate(struct vxlan_sock *vs, void *oiph,
1672
1667
static int vxlan_rcv (struct sock * sk , struct sk_buff * skb )
1673
1668
{
1674
1669
struct vxlan_vni_node * vninode = NULL ;
1670
+ const struct vxlanhdr * vh ;
1675
1671
struct vxlan_dev * vxlan ;
1676
1672
struct vxlan_sock * vs ;
1677
- struct vxlanhdr unparsed ;
1678
1673
struct vxlan_metadata _md ;
1679
1674
struct vxlan_metadata * md = & _md ;
1680
1675
__be16 protocol = htons (ETH_P_TEB );
@@ -1689,38 +1684,49 @@ static int vxlan_rcv(struct sock *sk, struct sk_buff *skb)
1689
1684
if (reason )
1690
1685
goto drop ;
1691
1686
1692
- unparsed = * vxlan_hdr (skb );
1687
+ vh = vxlan_hdr (skb );
1693
1688
/* VNI flag always required to be set */
1694
- if (!(unparsed . vx_flags & VXLAN_HF_VNI )) {
1689
+ if (!(vh -> vx_flags & VXLAN_HF_VNI )) {
1695
1690
netdev_dbg (skb -> dev , "invalid vxlan flags=%#x vni=%#x\n" ,
1696
- ntohl (vxlan_hdr (skb )-> vx_flags ),
1697
- ntohl (vxlan_hdr (skb )-> vx_vni ));
1691
+ ntohl (vh -> vx_flags ), ntohl (vh -> vx_vni ));
1698
1692
reason = SKB_DROP_REASON_VXLAN_INVALID_HDR ;
1699
1693
/* Return non vxlan pkt */
1700
1694
goto drop ;
1701
1695
}
1702
- unparsed .vx_flags &= ~VXLAN_HF_VNI ;
1703
- unparsed .vx_vni &= ~VXLAN_VNI_MASK ;
1704
1696
1705
1697
vs = rcu_dereference_sk_user_data (sk );
1706
1698
if (!vs )
1707
1699
goto drop ;
1708
1700
1709
- vni = vxlan_vni (vxlan_hdr ( skb ) -> vx_vni );
1701
+ vni = vxlan_vni (vh -> vx_vni );
1710
1702
1711
1703
vxlan = vxlan_vs_find_vni (vs , skb -> dev -> ifindex , vni , & vninode );
1712
1704
if (!vxlan ) {
1713
1705
reason = SKB_DROP_REASON_VXLAN_VNI_NOT_FOUND ;
1714
1706
goto drop ;
1715
1707
}
1716
1708
1717
- /* For backwards compatibility, only allow reserved fields to be
1718
- * used by VXLAN extensions if explicitly requested.
1719
- */
1720
- if (vs -> flags & VXLAN_F_GPE ) {
1721
- if (!vxlan_parse_gpe_proto (& unparsed , & protocol ))
1709
+ if (vh -> vx_flags & vxlan -> cfg .reserved_bits .vx_flags ||
1710
+ vh -> vx_vni & vxlan -> cfg .reserved_bits .vx_vni ) {
1711
+ /* If the header uses bits besides those enabled by the
1712
+ * netdevice configuration, treat this as a malformed packet.
1713
+ * This behavior diverges from VXLAN RFC (RFC7348) which
1714
+ * stipulates that bits in reserved in reserved fields are to be
1715
+ * ignored. The approach here maintains compatibility with
1716
+ * previous stack code, and also is more robust and provides a
1717
+ * little more security in adding extensions to VXLAN.
1718
+ */
1719
+ reason = SKB_DROP_REASON_VXLAN_INVALID_HDR ;
1720
+ DEV_STATS_INC (vxlan -> dev , rx_frame_errors );
1721
+ DEV_STATS_INC (vxlan -> dev , rx_errors );
1722
+ vxlan_vnifilter_count (vxlan , vni , vninode ,
1723
+ VXLAN_VNI_STATS_RX_ERRORS , 0 );
1724
+ goto drop ;
1725
+ }
1726
+
1727
+ if (vxlan -> cfg .flags & VXLAN_F_GPE ) {
1728
+ if (!vxlan_parse_gpe_proto (vh , & protocol ))
1722
1729
goto drop ;
1723
- unparsed .vx_flags &= ~VXLAN_GPE_USED_BITS ;
1724
1730
raw_proto = true;
1725
1731
}
1726
1732
@@ -1730,8 +1736,8 @@ static int vxlan_rcv(struct sock *sk, struct sk_buff *skb)
1730
1736
goto drop ;
1731
1737
}
1732
1738
1733
- if (vs -> flags & VXLAN_F_REMCSUM_RX ) {
1734
- reason = vxlan_remcsum (& unparsed , skb , vs -> flags );
1739
+ if (vxlan -> cfg . flags & VXLAN_F_REMCSUM_RX ) {
1740
+ reason = vxlan_remcsum (skb , vxlan -> cfg . flags );
1735
1741
if (unlikely (reason ))
1736
1742
goto drop ;
1737
1743
}
@@ -1756,25 +1762,12 @@ static int vxlan_rcv(struct sock *sk, struct sk_buff *skb)
1756
1762
memset (md , 0 , sizeof (* md ));
1757
1763
}
1758
1764
1759
- if (vs -> flags & VXLAN_F_GBP )
1760
- vxlan_parse_gbp_hdr (& unparsed , skb , vs -> flags , md );
1765
+ if (vxlan -> cfg . flags & VXLAN_F_GBP )
1766
+ vxlan_parse_gbp_hdr (skb , vxlan -> cfg . flags , md );
1761
1767
/* Note that GBP and GPE can never be active together. This is
1762
1768
* ensured in vxlan_dev_configure.
1763
1769
*/
1764
1770
1765
- if (unparsed .vx_flags || unparsed .vx_vni ) {
1766
- /* If there are any unprocessed flags remaining treat
1767
- * this as a malformed packet. This behavior diverges from
1768
- * VXLAN RFC (RFC7348) which stipulates that bits in reserved
1769
- * in reserved fields are to be ignored. The approach here
1770
- * maintains compatibility with previous stack code, and also
1771
- * is more robust and provides a little more security in
1772
- * adding extensions to VXLAN.
1773
- */
1774
- reason = SKB_DROP_REASON_VXLAN_INVALID_HDR ;
1775
- goto drop ;
1776
- }
1777
-
1778
1771
if (!raw_proto ) {
1779
1772
reason = vxlan_set_mac (vxlan , vs , skb , vni );
1780
1773
if (reason )
@@ -3435,6 +3428,7 @@ static const struct nla_policy vxlan_policy[IFLA_VXLAN_MAX + 1] = {
3435
3428
[IFLA_VXLAN_VNIFILTER ] = { .type = NLA_U8 },
3436
3429
[IFLA_VXLAN_LOCALBYPASS ] = NLA_POLICY_MAX (NLA_U8 , 1 ),
3437
3430
[IFLA_VXLAN_LABEL_POLICY ] = NLA_POLICY_MAX (NLA_U32 , VXLAN_LABEL_MAX ),
3431
+ [IFLA_VXLAN_RESERVED_BITS ] = NLA_POLICY_EXACT_LEN (sizeof (struct vxlanhdr )),
3438
3432
};
3439
3433
3440
3434
static int vxlan_validate (struct nlattr * tb [], struct nlattr * data [],
@@ -4070,6 +4064,10 @@ static int vxlan_nl2conf(struct nlattr *tb[], struct nlattr *data[],
4070
4064
struct net_device * dev , struct vxlan_config * conf ,
4071
4065
bool changelink , struct netlink_ext_ack * extack )
4072
4066
{
4067
+ struct vxlanhdr used_bits = {
4068
+ .vx_flags = VXLAN_HF_VNI ,
4069
+ .vx_vni = VXLAN_VNI_MASK ,
4070
+ };
4073
4071
struct vxlan_dev * vxlan = netdev_priv (dev );
4074
4072
int err = 0 ;
4075
4073
@@ -4296,13 +4294,16 @@ static int vxlan_nl2conf(struct nlattr *tb[], struct nlattr *data[],
4296
4294
extack );
4297
4295
if (err )
4298
4296
return err ;
4297
+ used_bits .vx_flags |= VXLAN_HF_RCO ;
4298
+ used_bits .vx_vni |= ~VXLAN_VNI_MASK ;
4299
4299
}
4300
4300
4301
4301
if (data [IFLA_VXLAN_GBP ]) {
4302
4302
err = vxlan_nl2flag (conf , data , IFLA_VXLAN_GBP ,
4303
4303
VXLAN_F_GBP , changelink , false, extack );
4304
4304
if (err )
4305
4305
return err ;
4306
+ used_bits .vx_flags |= VXLAN_GBP_USED_BITS ;
4306
4307
}
4307
4308
4308
4309
if (data [IFLA_VXLAN_GPE ]) {
@@ -4311,6 +4312,46 @@ static int vxlan_nl2conf(struct nlattr *tb[], struct nlattr *data[],
4311
4312
extack );
4312
4313
if (err )
4313
4314
return err ;
4315
+
4316
+ used_bits .vx_flags |= VXLAN_GPE_USED_BITS ;
4317
+ }
4318
+
4319
+ if (data [IFLA_VXLAN_RESERVED_BITS ]) {
4320
+ struct vxlanhdr reserved_bits ;
4321
+
4322
+ if (changelink ) {
4323
+ NL_SET_ERR_MSG_ATTR (extack ,
4324
+ data [IFLA_VXLAN_RESERVED_BITS ],
4325
+ "Cannot change reserved_bits" );
4326
+ return - EOPNOTSUPP ;
4327
+ }
4328
+
4329
+ nla_memcpy (& reserved_bits , data [IFLA_VXLAN_RESERVED_BITS ],
4330
+ sizeof (reserved_bits ));
4331
+ if (used_bits .vx_flags & reserved_bits .vx_flags ||
4332
+ used_bits .vx_vni & reserved_bits .vx_vni ) {
4333
+ __be64 ub_be64 , rb_be64 ;
4334
+
4335
+ memcpy (& ub_be64 , & used_bits , sizeof (ub_be64 ));
4336
+ memcpy (& rb_be64 , & reserved_bits , sizeof (rb_be64 ));
4337
+
4338
+ NL_SET_ERR_MSG_ATTR_FMT (extack ,
4339
+ data [IFLA_VXLAN_RESERVED_BITS ],
4340
+ "Used bits %#018llx cannot overlap reserved bits %#018llx" ,
4341
+ be64_to_cpu (ub_be64 ),
4342
+ be64_to_cpu (rb_be64 ));
4343
+ return - EINVAL ;
4344
+ }
4345
+
4346
+ conf -> reserved_bits = reserved_bits ;
4347
+ } else {
4348
+ /* For backwards compatibility, only allow reserved fields to be
4349
+ * used by VXLAN extensions if explicitly requested.
4350
+ */
4351
+ conf -> reserved_bits = (struct vxlanhdr ) {
4352
+ .vx_flags = ~used_bits .vx_flags ,
4353
+ .vx_vni = ~used_bits .vx_vni ,
4354
+ };
4314
4355
}
4315
4356
4316
4357
if (data [IFLA_VXLAN_REMCSUM_NOPARTIAL ]) {
@@ -4497,6 +4538,8 @@ static size_t vxlan_get_size(const struct net_device *dev)
4497
4538
nla_total_size (0 ) + /* IFLA_VXLAN_GPE */
4498
4539
nla_total_size (0 ) + /* IFLA_VXLAN_REMCSUM_NOPARTIAL */
4499
4540
nla_total_size (sizeof (__u8 )) + /* IFLA_VXLAN_VNIFILTER */
4541
+ /* IFLA_VXLAN_RESERVED_BITS */
4542
+ nla_total_size (sizeof (struct vxlanhdr )) +
4500
4543
0 ;
4501
4544
}
4502
4545
@@ -4599,6 +4642,11 @@ static int vxlan_fill_info(struct sk_buff *skb, const struct net_device *dev)
4599
4642
!!(vxlan -> cfg .flags & VXLAN_F_VNIFILTER )))
4600
4643
goto nla_put_failure ;
4601
4644
4645
+ if (nla_put (skb , IFLA_VXLAN_RESERVED_BITS ,
4646
+ sizeof (vxlan -> cfg .reserved_bits ),
4647
+ & vxlan -> cfg .reserved_bits ))
4648
+ goto nla_put_failure ;
4649
+
4602
4650
return 0 ;
4603
4651
4604
4652
nla_put_failure :
0 commit comments