ovn/controller/pinctrl.c
static void
pinctrl_handle_put_icmp4_frag_mtu(struct rconn *swconn,
                                  const struct flow *in_flow,
                                  struct dp_packet *pkt_in,
                                  struct ofputil_packet_in *pin,
                                  struct ofpbuf *userdata,
                                  struct ofpbuf *continuation)
{
    enum ofp_version version = rconn_get_version(swconn);
    enum ofputil_protocol proto = ofputil_protocol_from_ofp_version(version);
    struct dp_packet *pkt_out = NULL;

    /* This action only works for ICMPv4 packets. */
    if (!is_icmpv4(in_flow, NULL)) {
        static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
        VLOG_WARN_RL(&rl, "put_icmp4_frag_mtu action on non-ICMPv4 packet");
        goto exit;
    }

    ovs_be16 *mtu = ofpbuf_try_pull(userdata, sizeof *mtu);
    if (!mtu) {
        goto exit;
    }

    pkt_out = dp_packet_clone(pkt_in);
    pkt_out->l2_5_ofs = pkt_in->l2_5_ofs;
    pkt_out->l2_pad_size = pkt_in->l2_pad_size;
    pkt_out->l3_ofs = pkt_in->l3_ofs;
    pkt_out->l4_ofs = pkt_in->l4_ofs;

    struct ip_header *nh = dp_packet_l3(pkt_out);
    struct icmp_header *ih = dp_packet_l4(pkt_out);
    ovs_be16 old_frag_mtu = ih->icmp_fields.frag.mtu;
    ih->icmp_fields.frag.mtu = *mtu;
    ih->icmp_csum = recalc_csum16(ih->icmp_csum, old_frag_mtu, *mtu);
    nh->ip_csum = 0;
    nh->ip_csum = csum(nh, sizeof *nh);

    pin->packet = dp_packet_data(pkt_out);
    pin->packet_len = dp_packet_size(pkt_out);

exit:
    queue_msg(swconn, ofputil_encode_resume(pin, continuation, proto));
    if (pkt_out) {
        dp_packet_delete(pkt_out);
    }
}
/* Called with in the pinctrl_handler thread context. */
Called with in the pinctrl_handler thread context.
Called with in the pinctrl_handler thread context .
static void
pinctrl_handle_put_icmp4_frag_mtu(struct rconn *swconn,
                                  const struct flow *in_flow,
                                  struct dp_packet *pkt_in,
                                  struct ofputil_packet_in *pin,
                                  struct ofpbuf *userdata,
                                  struct ofpbuf *continuation)
{
    enum ofp_version version = rconn_get_version(swconn);
    enum ofputil_protocol proto = ofputil_protocol_from_ofp_version(version);
    struct dp_packet *pkt_out = NULL;
    if (!is_icmpv4(in_flow, NULL)) {
        static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
        VLOG_WARN_RL(&rl, "put_icmp4_frag_mtu action on non-ICMPv4 packet");
        goto exit;
    }
    ovs_be16 *mtu = ofpbuf_try_pull(userdata, sizeof *mtu);
    if (!mtu) {
        goto exit;
    }
    pkt_out = dp_packet_clone(pkt_in);
    pkt_out->l2_5_ofs = pkt_in->l2_5_ofs;
    pkt_out->l2_pad_size = pkt_in->l2_pad_size;
    pkt_out->l3_ofs = pkt_in->l3_ofs;
    pkt_out->l4_ofs = pkt_in->l4_ofs;
    struct ip_header *nh = dp_packet_l3(pkt_out);
    struct icmp_header *ih = dp_packet_l4(pkt_out);
    ovs_be16 old_frag_mtu = ih->icmp_fields.frag.mtu;
    ih->icmp_fields.frag.mtu = *mtu;
    ih->icmp_csum = recalc_csum16(ih->icmp_csum, old_frag_mtu, *mtu);
    nh->ip_csum = 0;
    nh->ip_csum = csum(nh, sizeof *nh);
    pin->packet = dp_packet_data(pkt_out);
    pin->packet_len = dp_packet_size(pkt_out);
exit:
    queue_msg(swconn, ofputil_encode_resume(pin, continuation, proto));
    if (pkt_out) {
        dp_packet_delete(pkt_out);
    }
}
static void pinctrl_handle_put_icmp4_frag_mtu ( struct rconn * swconn , const struct flow * in_flow , struct dp_packet * pkt_in , struct ofputil_packet_in * pin , struct ofpbuf * userdata , struct ofpbuf * continuation ) { enum ofp_version version = rconn_get_version ( swconn ) ; enum ofputil_protocol proto = ofputil_protocol_from_ofp_version ( version ) ; struct dp_packet * pkt_out = NULL ; if ( ! is_icmpv4 ( in_flow , NULL ) ) { static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT ( 1 , 5 ) ; VLOG_WARN_RL ( & rl , " " ) ; goto exit ; } ovs_be16 * mtu = ofpbuf_try_pull ( userdata , sizeof * mtu ) ; if ( ! mtu ) { goto exit ; } pkt_out = dp_packet_clone ( pkt_in ) ; pkt_out -> l2_5_ofs = pkt_in -> l2_5_ofs ; pkt_out -> l2_pad_size = pkt_in -> l2_pad_size ; pkt_out -> l3_ofs = pkt_in -> l3_ofs ; pkt_out -> l4_ofs = pkt_in -> l4_ofs ; struct ip_header * nh = dp_packet_l3 ( pkt_out ) ; struct icmp_header * ih = dp_packet_l4 ( pkt_out ) ; ovs_be16 old_frag_mtu = ih -> icmp_fields . frag . mtu ; ih -> icmp_fields . frag . mtu = * mtu ; ih -> icmp_csum = recalc_csum16 ( ih -> icmp_csum , old_frag_mtu , * mtu ) ; nh -> ip_csum = 0 ; nh -> ip_csum = csum ( nh , sizeof * nh ) ; pin -> packet = dp_packet_data ( pkt_out ) ; pin -> packet_len = dp_packet_size ( pkt_out ) ; exit : queue_msg ( swconn , ofputil_encode_resume ( pin , continuation , proto ) ) ; if ( pkt_out ) { dp_packet_delete ( pkt_out ) ; } }
Called with in the pinctrl_handler thread context.
Called with in the pinctrl_handler thread context .
/* This action only works for ICMPv4 packets. */