Skip to content

Commit

Permalink
Don't forward packets with ttl1 (#478)
Browse files Browse the repository at this point in the history
* Don't forward packets with ttl1

* seperate tables for v4 and v6
  • Loading branch information
DanG100 authored Sep 18, 2024
1 parent 2f9ec57 commit efc1b32
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 41 deletions.
5 changes: 2 additions & 3 deletions dataplane/saiserver/ports.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,10 @@ func getPreIngressPipeline() []*fwdpb.ActionDesc {
func getL3Pipeline() []*fwdpb.ActionDesc {
return []*fwdpb.ActionDesc{
fwdconfig.Action(fwdconfig.LookupAction(IngressActionTable)).Build(), // Run ingress action.
fwdconfig.Action(fwdconfig.LookupAction(invalidPacketTable)).Build(), // Do not forward packets with invalid addresses
fwdconfig.Action(fwdconfig.DecapAction(fwdpb.PacketHeaderId_PACKET_HEADER_ID_ETHERNET)).Build(), // Decap L2 header.
fwdconfig.Action(fwdconfig.LookupAction(FIBSelectorTable)).Build(), // Lookup in FIB. // Do not forward packets with invalid fields.
fwdconfig.Action(fwdconfig.UpdateAction(fwdpb.UpdateType_UPDATE_TYPE_DEC, fwdpb.PacketFieldNum_PACKET_FIELD_NUM_IP_HOP).WithValue([]byte{0x1})).Build(), // Decrement TTL.
fwdconfig.Action(fwdconfig.LookupAction(FIBSelectorTable)).Build(), // Lookup in FIB.
fwdconfig.Action(fwdconfig.EncapAction(fwdpb.PacketHeaderId_PACKET_HEADER_ID_ETHERNET)).Build(), // Encap L2 header.
fwdconfig.Action(fwdconfig.EncapAction(fwdpb.PacketHeaderId_PACKET_HEADER_ID_ETHERNET)).Build(), // Encap L2 header. // Drop invalid packets the FIB.
fwdconfig.Action(fwdconfig.LookupAction(outputIfaceTable)).Build(), // Match interface to port
fwdconfig.Action(fwdconfig.LookupAction(NeighborTable)).Build(), // Lookup in the neighbor table.
}
Expand Down
100 changes: 62 additions & 38 deletions dataplane/saiserver/switch.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,8 @@ const (
VlanTable = "vlan"
L2MCGroupTable = "l2mcg"
policerTabler = "policerTable"
invalidPacketTable = "invalid-ip"
invalidIngressV4Table = "invalid-ingress-v4"
invalidIngressV6Table = "invalid-ingress-v6"
DefaultVlanId = 1
)

Expand Down Expand Up @@ -851,62 +852,71 @@ func (sw *saiSwitch) CreateSwitch(ctx context.Context, _ *saipb.CreateSwitchRequ
// Set up rules to drop packets that contain invalid IP or ttl == 0.
// https://www.rfc-editor.org/rfc/rfc1812#section-5.3.7
func (sw *saiSwitch) createInvalidPacketFilter(ctx context.Context) error {
_, err := sw.dataplane.TableCreate(ctx, &fwdpb.TableCreateRequest{
ContextId: &fwdpb.ContextId{Id: sw.dataplane.ID()},
Desc: &fwdpb.TableDesc{
Actions: []*fwdpb.ActionDesc{{ActionType: fwdpb.ActionType_ACTION_TYPE_CONTINUE}},
TableType: fwdpb.TableType_TABLE_TYPE_FLOW,
TableId: &fwdpb.TableId{ObjectId: &fwdpb.ObjectId{Id: invalidPacketTable}},
Table: &fwdpb.TableDesc_Flow{
Flow: &fwdpb.FlowTableDesc{
BankCount: 1,
},
},
ips := map[string]map[fwdpb.PacketFieldNum][]string{
invalidIngressV4Table: {
fwdpb.PacketFieldNum_PACKET_FIELD_NUM_IP_ADDR_SRC: {"224.0.0.0/4", "127.0.0.0/8"},
fwdpb.PacketFieldNum_PACKET_FIELD_NUM_IP_ADDR_DST: {"224.0.0.0/4", "127.0.0.0/8", "255.255.255.255/24"},
},
invalidIngressV6Table: {
fwdpb.PacketFieldNum_PACKET_FIELD_NUM_IP_ADDR_SRC: {"ff00::/8"},
fwdpb.PacketFieldNum_PACKET_FIELD_NUM_IP_ADDR_DST: {"ff00::/8", "fe80::/10"},
},
})
if err != nil {
return err
}
// Packets can't have multicast, or loopback IP as the source IP.
invalidSrcIP := []string{"224.0.0.0/4", "ff00::/8", "127.0.0.0/8"}
for _, ip := range invalidSrcIP {
_, prefix, err := net.ParseCIDR(ip)
// Only unicast MAC address are processed at this stage, so multicast IPs are invalid
for table, ipsByField := range ips {
_, err := sw.dataplane.TableCreate(ctx, &fwdpb.TableCreateRequest{
ContextId: &fwdpb.ContextId{Id: sw.dataplane.ID()},
Desc: &fwdpb.TableDesc{
Actions: []*fwdpb.ActionDesc{{ActionType: fwdpb.ActionType_ACTION_TYPE_CONTINUE}},
TableType: fwdpb.TableType_TABLE_TYPE_FLOW,
TableId: &fwdpb.TableId{ObjectId: &fwdpb.ObjectId{Id: table}},
Table: &fwdpb.TableDesc_Flow{
Flow: &fwdpb.FlowTableDesc{
BankCount: 1,
},
},
},
})
if err != nil {
return err
}
req := fwdconfig.TableEntryAddRequest(sw.dataplane.ID(), invalidPacketTable).

for field, ips := range ipsByField {
for _, ip := range ips {
_, prefix, err := net.ParseCIDR(ip)
if err != nil {
return err
}
req := fwdconfig.TableEntryAddRequest(sw.dataplane.ID(), table).
AppendEntry(
fwdconfig.EntryDesc(fwdconfig.FlowEntry(fwdconfig.PacketFieldMaskedBytes(field).WithBytes(prefix.IP, prefix.Mask))),
fwdconfig.Action(fwdconfig.DropAction()),
).Build()
if _, err := sw.dataplane.TableEntryAdd(ctx, req); err != nil {
return err
}
}
}
// Before the TTL is decremented and after the packets may be punted, drop packet with TTL == 1 or TTL == 0.
req := fwdconfig.TableEntryAddRequest(sw.dataplane.ID(), table).
AppendEntry(
fwdconfig.EntryDesc(fwdconfig.FlowEntry(fwdconfig.PacketFieldMaskedBytes(fwdpb.PacketFieldNum_PACKET_FIELD_NUM_IP_ADDR_SRC).WithBytes(prefix.IP, prefix.Mask))),
fwdconfig.EntryDesc(fwdconfig.FlowEntry(fwdconfig.PacketFieldMaskedBytes(fwdpb.PacketFieldNum_PACKET_FIELD_NUM_IP_HOP).WithBytes([]byte{0x00}, []byte{0xFF}))),
fwdconfig.Action(fwdconfig.DropAction()),
).Build()
if _, err := sw.dataplane.TableEntryAdd(ctx, req); err != nil {
return err
}
}
// Only unicast MAC address are processed at this stage, so multicast IPs are invalid
invalidDstIP := []string{"224.0.0.0/4", "ff00::/8", "fe80::/10", "127.0.0.0/8", "255.255.255.255/24"}
for _, ip := range invalidDstIP {
_, prefix, err := net.ParseCIDR(ip)
if err != nil {
return err
}
req := fwdconfig.TableEntryAddRequest(sw.dataplane.ID(), invalidPacketTable).
req = fwdconfig.TableEntryAddRequest(sw.dataplane.ID(), table).
AppendEntry(
fwdconfig.EntryDesc(fwdconfig.FlowEntry(fwdconfig.PacketFieldMaskedBytes(fwdpb.PacketFieldNum_PACKET_FIELD_NUM_IP_ADDR_DST).WithBytes(prefix.IP, prefix.Mask))),
fwdconfig.EntryDesc(fwdconfig.FlowEntry(fwdconfig.PacketFieldMaskedBytes(fwdpb.PacketFieldNum_PACKET_FIELD_NUM_IP_HOP).WithBytes([]byte{0x01}, []byte{0xFF}))),
fwdconfig.Action(fwdconfig.DropAction()),
).Build()
if _, err := sw.dataplane.TableEntryAdd(ctx, req); err != nil {
return err
}
}
req := fwdconfig.TableEntryAddRequest(sw.dataplane.ID(), invalidPacketTable).
AppendEntry(
fwdconfig.EntryDesc(fwdconfig.FlowEntry(fwdconfig.PacketFieldMaskedBytes(fwdpb.PacketFieldNum_PACKET_FIELD_NUM_IP_HOP).WithBytes([]byte{0x00}, []byte{0xFF}))),
fwdconfig.Action(fwdconfig.DropAction()),
).Build()
if _, err := sw.dataplane.TableEntryAdd(ctx, req); err != nil {
return err
}

return nil
}

Expand Down Expand Up @@ -1056,6 +1066,13 @@ func createFIBSelector(ctx context.Context, id string, c switchDataplaneAPI) err
TableId: &fwdpb.TableId{ObjectId: &fwdpb.ObjectId{Id: FIBV4Table}},
},
},
}, {
ActionType: fwdpb.ActionType_ACTION_TYPE_LOOKUP,
Action: &fwdpb.ActionDesc_Lookup{
Lookup: &fwdpb.LookupActionDesc{
TableId: &fwdpb.TableId{ObjectId: &fwdpb.ObjectId{Id: invalidIngressV4Table}},
},
},
}},
}, {
EntryDesc: &fwdpb.EntryDesc{
Expand All @@ -1075,6 +1092,13 @@ func createFIBSelector(ctx context.Context, id string, c switchDataplaneAPI) err
TableId: &fwdpb.TableId{ObjectId: &fwdpb.ObjectId{Id: FIBV6Table}},
},
},
}, {
ActionType: fwdpb.ActionType_ACTION_TYPE_LOOKUP,
Action: &fwdpb.ActionDesc_Lookup{
Lookup: &fwdpb.LookupActionDesc{
TableId: &fwdpb.TableId{ObjectId: &fwdpb.ObjectId{Id: invalidIngressV6Table}},
},
},
}},
}},
}
Expand Down

0 comments on commit efc1b32

Please sign in to comment.