@@ -79,3 +79,198 @@ pub const ICMPV6_ROUTER_SOLICITATION: u8 = 133;
7979pub const ICMPV6_ROUTER_ADVERTISEMENT : u8 = 134 ;
8080pub const ICMPV6_NEIGHBOR_SOLICITATION : u8 = 135 ;
8181pub const ICMPV6_NEIGHBOR_ADVERTISEMENT : u8 = 136 ;
82+
83+ // IP protocols for security rules
84+ pub const IPPROTO_ICMP : u8 = 1 ;
85+ pub const IPPROTO_TCP : u8 = 6 ;
86+
87+ // Security rule directions
88+ pub const DIRECTION_INGRESS : u8 = 0 ;
89+ pub const DIRECTION_EGRESS : u8 = 1 ;
90+
91+ // Security rule protocols (0 = all)
92+ pub const PROTO_ALL : u8 = 0 ;
93+ // IPPROTO_ICMP = 1 (already defined above)
94+ // IPPROTO_TCP = 6 (already defined above)
95+ // IPPROTO_UDP = 17 (already defined above)
96+ // IPPROTO_ICMPV6 = 58 (already defined above)
97+
98+ // Connection tracking states
99+ pub const CT_STATE_NEW : u8 = 0 ;
100+ pub const CT_STATE_ESTABLISHED : u8 = 1 ;
101+ pub const CT_STATE_RELATED : u8 = 2 ;
102+
103+ // Connection tracking flags
104+ pub const CT_FLAG_SEEN_REPLY : u8 = 1 ;
105+ pub const CT_FLAG_ASSURED : u8 = 2 ;
106+
107+ /// Security rule for packet filtering
108+ /// Rules are always "allow" - if ANY rule matches, packet is allowed
109+ #[ repr( C ) ]
110+ #[ derive( Clone , Copy ) ]
111+ pub struct SecurityRule {
112+ /// Rule is active (1) or disabled (0)
113+ pub enabled : u8 ,
114+ /// Direction: 0=ingress (to VM), 1=egress (from VM)
115+ pub direction : u8 ,
116+ /// IP protocol: 0=all, 1=ICMP, 6=TCP, 17=UDP, 58=ICMPv6
117+ pub protocol : u8 ,
118+ /// IP version: 4=IPv4, 6=IPv6, 0=both
119+ pub ip_version : u8 ,
120+ /// Start of port range (inclusive), 0 = any
121+ pub port_start : u16 ,
122+ /// End of port range (inclusive), 0 = any
123+ pub port_end : u16 ,
124+ /// CIDR network address (IPv4 in first 4 bytes, IPv6 uses all 16)
125+ pub cidr_addr : [ u8 ; 16 ] ,
126+ /// CIDR prefix length (0-32 for IPv4, 0-128 for IPv6)
127+ pub cidr_prefix_len : u8 ,
128+ _padding : [ u8 ; 3 ] ,
129+ }
130+
131+ impl SecurityRule {
132+ pub const fn new ( ) -> Self {
133+ Self {
134+ enabled : 0 ,
135+ direction : 0 ,
136+ protocol : 0 ,
137+ ip_version : 0 ,
138+ port_start : 0 ,
139+ port_end : 0 ,
140+ cidr_addr : [ 0 ; 16 ] ,
141+ cidr_prefix_len : 0 ,
142+ _padding : [ 0 ; 3 ] ,
143+ }
144+ }
145+ }
146+
147+ /// Connection tracking key (5-tuple + ip version)
148+ #[ repr( C ) ]
149+ #[ derive( Clone , Copy ) ]
150+ pub struct ConnTrackKey {
151+ /// Source IP address (IPv4: first 4 bytes, IPv6: all 16)
152+ pub src_addr : [ u8 ; 16 ] ,
153+ /// Destination IP address (IPv4: first 4 bytes, IPv6: all 16)
154+ pub dst_addr : [ u8 ; 16 ] ,
155+ /// Source port (0 for ICMP)
156+ pub src_port : u16 ,
157+ /// Destination port (0 for ICMP, but stores ICMP id)
158+ pub dst_port : u16 ,
159+ /// IP protocol: 1=ICMP, 6=TCP, 17=UDP, 58=ICMPv6
160+ pub protocol : u8 ,
161+ /// IP version: 4 or 6
162+ pub ip_version : u8 ,
163+ /// Padding for alignment
164+ pub _pad : [ u8 ; 2 ] ,
165+ }
166+
167+ impl ConnTrackKey {
168+ pub const fn new ( ) -> Self {
169+ Self {
170+ src_addr : [ 0 ; 16 ] ,
171+ dst_addr : [ 0 ; 16 ] ,
172+ src_port : 0 ,
173+ dst_port : 0 ,
174+ protocol : 0 ,
175+ ip_version : 0 ,
176+ _pad : [ 0 ; 2 ] ,
177+ }
178+ }
179+
180+ /// Create reverse key for reply traffic lookup
181+ pub const fn reverse ( & self ) -> Self {
182+ Self {
183+ src_addr : self . dst_addr ,
184+ dst_addr : self . src_addr ,
185+ src_port : self . dst_port ,
186+ dst_port : self . src_port ,
187+ protocol : self . protocol ,
188+ ip_version : self . ip_version ,
189+ _pad : [ 0 ; 2 ] ,
190+ }
191+ }
192+
193+ /// Create a new key with all fields specified
194+ pub const fn from_tuple (
195+ src_addr : [ u8 ; 16 ] ,
196+ dst_addr : [ u8 ; 16 ] ,
197+ src_port : u16 ,
198+ dst_port : u16 ,
199+ protocol : u8 ,
200+ ip_version : u8 ,
201+ ) -> Self {
202+ Self {
203+ src_addr,
204+ dst_addr,
205+ src_port,
206+ dst_port,
207+ protocol,
208+ ip_version,
209+ _pad : [ 0 ; 2 ] ,
210+ }
211+ }
212+ }
213+
214+ /// Connection tracking entry
215+ #[ repr( C ) ]
216+ #[ derive( Clone , Copy ) ]
217+ pub struct ConnTrackEntry {
218+ /// Connection state (CT_STATE_*)
219+ pub state : u8 ,
220+ /// Flags (CT_FLAG_*)
221+ pub flags : u8 ,
222+ /// Padding for alignment
223+ pub _pad : [ u8 ; 2 ] ,
224+ /// Timestamp of last seen packet (nanoseconds since boot)
225+ pub last_seen_ns : u64 ,
226+ /// Total packet count for this connection
227+ pub packet_count : u64 ,
228+ }
229+
230+ impl ConnTrackEntry {
231+ pub const fn new ( ) -> Self {
232+ Self {
233+ state : CT_STATE_NEW ,
234+ flags : 0 ,
235+ _pad : [ 0 ; 2 ] ,
236+ last_seen_ns : 0 ,
237+ packet_count : 0 ,
238+ }
239+ }
240+
241+ /// Create a new entry with specified state and timestamp
242+ pub const fn with_state ( state : u8 , last_seen_ns : u64 ) -> Self {
243+ Self {
244+ state,
245+ flags : 0 ,
246+ _pad : [ 0 ; 2 ] ,
247+ last_seen_ns,
248+ packet_count : 1 ,
249+ }
250+ }
251+ }
252+
253+ /// NIC security configuration
254+ /// Maps NIC ifindex to its security settings
255+ #[ repr( C ) ]
256+ #[ derive( Clone , Copy ) ]
257+ pub struct NicSecurityConfig {
258+ /// Whether security filtering is enabled for this NIC
259+ pub enabled : u8 ,
260+ _padding : [ u8 ; 3 ] ,
261+ /// Start index into SECURITY_RULES map for this NIC's rules
262+ pub rules_start : u32 ,
263+ /// Number of rules for this NIC
264+ pub rules_count : u32 ,
265+ }
266+
267+ impl NicSecurityConfig {
268+ pub const fn new ( ) -> Self {
269+ Self {
270+ enabled : 0 ,
271+ _padding : [ 0 ; 3 ] ,
272+ rules_start : 0 ,
273+ rules_count : 0 ,
274+ }
275+ }
276+ }
0 commit comments