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_
);
54 enum ct_update_res ret
= CT_UPDATE_VALID
;
56 if (reply
&& conn
->state
== ICMPS_FIRST
) {
57 conn
->state
= ICMPS_REPLY
;
58 } else if (conn
->state
== ICMPS_FIRST
) {
59 ret
= CT_UPDATE_VALID_NEW
;
62 conn_update_expiration(ct
, &conn
->up
, icmp_timeouts
[conn
->state
], now
);
67 icmp4_valid_new(struct dp_packet
*pkt
)
69 struct icmp_header
*icmp
= dp_packet_l4(pkt
);
71 return icmp
->icmp_type
== ICMP4_ECHO_REQUEST
72 || icmp
->icmp_type
== ICMP4_INFOREQUEST
73 || icmp
->icmp_type
== ICMP4_TIMESTAMP
;
77 icmp6_valid_new(struct dp_packet
*pkt
)
79 struct icmp6_header
*icmp6
= dp_packet_l4(pkt
);
81 return icmp6
->icmp6_type
== ICMP6_ECHO_REQUEST
;
85 icmp_new_conn(struct conntrack
*ct
, struct dp_packet
*pkt OVS_UNUSED
,
86 long long now
, uint32_t tp_id
)
88 struct conn_icmp
*conn
= xzalloc(sizeof *conn
);
89 conn
->state
= ICMPS_FIRST
;
90 conn
->up
.tp_id
= tp_id
;
92 conn_init_expiration(ct
, &conn
->up
, icmp_timeouts
[conn
->state
], now
);
96 struct ct_l4_proto ct_proto_icmp4
= {
97 .new_conn
= icmp_new_conn
,
98 .valid_new
= icmp4_valid_new
,
99 .conn_update
= icmp_conn_update
,
102 struct ct_l4_proto ct_proto_icmp6
= {
103 .new_conn
= icmp_new_conn
,
104 .valid_new
= icmp6_valid_new
,
105 .conn_update
= icmp_conn_update
,