2 * Copyright (c) 2015-2019 Nicira, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
20 #include <sys/types.h>
21 #include <netinet/in.h>
22 #include <netinet/icmp6.h>
24 #include "conntrack-private.h"
25 #include "conntrack-tp.h"
26 #include "dp-packet.h"
28 enum OVS_PACKED_ENUM icmp_state
{
35 enum icmp_state state
; /* 'conn' lock protected. */
38 static const enum ct_timeout icmp_timeouts
[] = {
39 [ICMPS_FIRST
] = CT_TM_ICMP_FIRST
,
40 [ICMPS_REPLY
] = CT_TM_ICMP_REPLY
,
43 static struct conn_icmp
*
44 conn_icmp_cast(const struct conn
*conn
)
46 return CONTAINER_OF(conn
, struct conn_icmp
, up
);
49 static enum ct_update_res
50 icmp_conn_update(struct conntrack
*ct
, struct conn
*conn_
,
51 struct dp_packet
*pkt OVS_UNUSED
, bool reply
, long long now
)
53 struct conn_icmp
*conn
= conn_icmp_cast(conn_
);
55 if (reply
&& conn
->state
== ICMPS_FIRST
) {
56 conn
->state
= ICMPS_REPLY
;
59 conn_update_expiration(ct
, &conn
->up
, icmp_timeouts
[conn
->state
], now
);
60 return CT_UPDATE_VALID
;
64 icmp4_valid_new(struct dp_packet
*pkt
)
66 struct icmp_header
*icmp
= dp_packet_l4(pkt
);
68 return icmp
->icmp_type
== ICMP4_ECHO_REQUEST
69 || icmp
->icmp_type
== ICMP4_INFOREQUEST
70 || icmp
->icmp_type
== ICMP4_TIMESTAMP
;
74 icmp6_valid_new(struct dp_packet
*pkt
)
76 struct icmp6_header
*icmp6
= dp_packet_l4(pkt
);
78 return icmp6
->icmp6_type
== ICMP6_ECHO_REQUEST
;
82 icmp_new_conn(struct conntrack
*ct
, struct dp_packet
*pkt OVS_UNUSED
,
83 long long now
, uint32_t tp_id
)
85 struct conn_icmp
*conn
= xzalloc(sizeof *conn
);
86 conn
->state
= ICMPS_FIRST
;
87 conn
->up
.tp_id
= tp_id
;
89 conn_init_expiration(ct
, &conn
->up
, icmp_timeouts
[conn
->state
], now
);
93 struct ct_l4_proto ct_proto_icmp4
= {
94 .new_conn
= icmp_new_conn
,
95 .valid_new
= icmp4_valid_new
,
96 .conn_update
= icmp_conn_update
,
99 struct ct_l4_proto ct_proto_icmp6
= {
100 .new_conn
= icmp_new_conn
,
101 .valid_new
= icmp6_valid_new
,
102 .conn_update
= icmp_conn_update
,