Annotation of embedaddon/strongswan/src/libcharon/config/child_cfg.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2008-2019 Tobias Brunner
                      3:  * Copyright (C) 2016 Andreas Steffen
                      4:  * Copyright (C) 2005-2007 Martin Willi
                      5:  * Copyright (C) 2005 Jan Hutter
                      6:  * HSR Hochschule fuer Technik Rapperswil
                      7:  *
                      8:  * This program is free software; you can redistribute it and/or modify it
                      9:  * under the terms of the GNU General Public License as published by the
                     10:  * Free Software Foundation; either version 2 of the License, or (at your
                     11:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
                     12:  *
                     13:  * This program is distributed in the hope that it will be useful, but
                     14:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     15:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     16:  * for more details.
                     17:  */
                     18: 
                     19: #include "child_cfg.h"
                     20: 
                     21: #include <stdint.h>
                     22: 
                     23: #include <daemon.h>
                     24: 
                     25: ENUM(action_names, ACTION_NONE, ACTION_RESTART,
                     26:        "clear",
                     27:        "hold",
                     28:        "restart",
                     29: );
                     30: 
                     31: /** Default replay window size, if not set using charon.replay_window */
                     32: #define DEFAULT_REPLAY_WINDOW 32
                     33: 
                     34: typedef struct private_child_cfg_t private_child_cfg_t;
                     35: 
                     36: /**
                     37:  * Private data of an child_cfg_t object
                     38:  */
                     39: struct private_child_cfg_t {
                     40: 
                     41:        /**
                     42:         * Public part
                     43:         */
                     44:        child_cfg_t public;
                     45: 
                     46:        /**
                     47:         * Number of references hold by others to this child_cfg
                     48:         */
                     49:        refcount_t refcount;
                     50: 
                     51:        /**
                     52:         * Name of the child_cfg, used to query it
                     53:         */
                     54:        char *name;
                     55: 
                     56:        /**
                     57:         * Options
                     58:         */
                     59:        child_cfg_option_t options;
                     60: 
                     61:        /**
                     62:         * list for all proposals
                     63:         */
                     64:        linked_list_t *proposals;
                     65: 
                     66:        /**
                     67:         * list for traffic selectors for my site
                     68:         */
                     69:        linked_list_t *my_ts;
                     70: 
                     71:        /**
                     72:         * list for traffic selectors for others site
                     73:         */
                     74:        linked_list_t *other_ts;
                     75: 
                     76:        /**
                     77:         * updown script
                     78:         */
                     79:        char *updown;
                     80: 
                     81:        /**
                     82:         * Mode to propose for a initiated CHILD: tunnel/transport
                     83:         */
                     84:        ipsec_mode_t mode;
                     85: 
                     86:        /**
                     87:         * action to take to start CHILD_SA
                     88:         */
                     89:        action_t start_action;
                     90: 
                     91:        /**
                     92:         * action to take on DPD
                     93:         */
                     94:        action_t dpd_action;
                     95: 
                     96:        /**
                     97:         * action to take on CHILD_SA close
                     98:         */
                     99:        action_t close_action;
                    100: 
                    101:        /**
                    102:         * CHILD_SA lifetime config
                    103:         */
                    104:        lifetime_cfg_t lifetime;
                    105: 
                    106:        /**
                    107:         * Inactivity timeout
                    108:         */
                    109:        uint32_t inactivity;
                    110: 
                    111:        /**
                    112:         * Reqid to install CHILD_SA with
                    113:         */
                    114:        uint32_t reqid;
                    115: 
                    116:        /**
                    117:         * Optional interface ID to use for inbound CHILD_SA
                    118:         */
                    119:        uint32_t if_id_in;
                    120: 
                    121:        /**
                    122:         * Optional interface ID to use for outbound CHILD_SA
                    123:         */
                    124:        uint32_t if_id_out;
                    125: 
                    126:        /**
                    127:         * Optional mark to install inbound CHILD_SA with
                    128:         */
                    129:        mark_t mark_in;
                    130: 
                    131:        /**
                    132:         * Optional mark to install outbound CHILD_SA with
                    133:         */
                    134:        mark_t mark_out;
                    135: 
                    136:        /**
                    137:         * Optional mark to set to packets after inbound processing
                    138:         */
                    139:        mark_t set_mark_in;
                    140: 
                    141:        /**
                    142:         * Optional mark to set to packets after outbound processing
                    143:         */
                    144:        mark_t set_mark_out;
                    145: 
                    146:        /**
                    147:         * Traffic Flow Confidentiality padding, if enabled
                    148:         */
                    149:        uint32_t tfc;
                    150: 
                    151:        /**
                    152:         * Optional manually-set IPsec policy priorities
                    153:         */
                    154:        uint32_t manual_prio;
                    155: 
                    156:        /**
                    157:         * Optional restriction of IPsec policy to a given network interface
                    158:         */
                    159:        char *interface;
                    160: 
                    161:        /**
                    162:         * anti-replay window size
                    163:         */
                    164:        uint32_t replay_window;
                    165: 
                    166:        /**
                    167:         * HW offload mode
                    168:         */
                    169:        hw_offload_t hw_offload;
                    170: 
                    171:        /**
                    172:         * DS header field copy mode
                    173:         */
                    174:        dscp_copy_t copy_dscp;
                    175: };
                    176: 
                    177: METHOD(child_cfg_t, get_name, char*,
                    178:        private_child_cfg_t *this)
                    179: {
                    180:        return this->name;
                    181: }
                    182: 
                    183: METHOD(child_cfg_t, has_option, bool,
                    184:        private_child_cfg_t *this, child_cfg_option_t option)
                    185: {
                    186:        return this->options & option;
                    187: }
                    188: 
                    189: METHOD(child_cfg_t, add_proposal, void,
                    190:        private_child_cfg_t *this, proposal_t *proposal)
                    191: {
                    192:        if (proposal)
                    193:        {
                    194:                this->proposals->insert_last(this->proposals, proposal);
                    195:        }
                    196: }
                    197: 
                    198: CALLBACK(match_proposal, bool,
                    199:        proposal_t *item, va_list args)
                    200: {
                    201:        proposal_t *proposal;
                    202: 
                    203:        VA_ARGS_VGET(args, proposal);
                    204:        return item->equals(item, proposal);
                    205: }
                    206: 
                    207: METHOD(child_cfg_t, get_proposals, linked_list_t*,
                    208:        private_child_cfg_t *this, bool strip_dh)
                    209: {
                    210:        enumerator_t *enumerator;
                    211:        proposal_t *current;
                    212:        proposal_selection_flag_t flags = 0;
                    213:        linked_list_t *proposals = linked_list_create();
                    214: 
                    215:        if (strip_dh)
                    216:        {
                    217:                flags |= PROPOSAL_SKIP_DH;
                    218:        }
                    219: 
                    220:        enumerator = this->proposals->create_enumerator(this->proposals);
                    221:        while (enumerator->enumerate(enumerator, &current))
                    222:        {
                    223:                current = current->clone(current, flags);
                    224:                if (proposals->find_first(proposals, match_proposal, NULL, current))
                    225:                {
                    226:                        current->destroy(current);
                    227:                        continue;
                    228:                }
                    229:                proposals->insert_last(proposals, current);
                    230:        }
                    231:        enumerator->destroy(enumerator);
                    232: 
                    233:        DBG2(DBG_CFG, "configured proposals: %#P", proposals);
                    234: 
                    235:        return proposals;
                    236: }
                    237: 
                    238: METHOD(child_cfg_t, select_proposal, proposal_t*,
                    239:        private_child_cfg_t*this, linked_list_t *proposals,
                    240:        proposal_selection_flag_t flags)
                    241: {
                    242:        return proposal_select(this->proposals, proposals, flags);
                    243: }
                    244: 
                    245: METHOD(child_cfg_t, add_traffic_selector, void,
                    246:        private_child_cfg_t *this, bool local, traffic_selector_t *ts)
                    247: {
                    248:        if (local)
                    249:        {
                    250:                this->my_ts->insert_last(this->my_ts, ts);
                    251:        }
                    252:        else
                    253:        {
                    254:                this->other_ts->insert_last(this->other_ts, ts);
                    255:        }
                    256: }
                    257: 
                    258: METHOD(child_cfg_t, get_traffic_selectors, linked_list_t*,
                    259:        private_child_cfg_t *this, bool local, linked_list_t *supplied,
                    260:        linked_list_t *hosts, bool log)
                    261: {
                    262:        enumerator_t *e1, *e2;
                    263:        traffic_selector_t *ts1, *ts2, *selected;
                    264:        linked_list_t *result, *derived;
                    265:        host_t *host;
                    266: 
                    267:        result = linked_list_create();
                    268:        derived = linked_list_create();
                    269:        if (local)
                    270:        {
                    271:                e1 = this->my_ts->create_enumerator(this->my_ts);
                    272:        }
                    273:        else
                    274:        {
                    275:                e1 = this->other_ts->create_enumerator(this->other_ts);
                    276:        }
                    277:        /* in a first step, replace "dynamic" TS with the host list */
                    278:        while (e1->enumerate(e1, &ts1))
                    279:        {
                    280:                if (hosts && hosts->get_count(hosts))
                    281:                {       /* set hosts if TS is dynamic or as initiator in transport mode */
                    282:                        bool dynamic = ts1->is_dynamic(ts1),
                    283:                                 proxy_mode = has_option(this, OPT_PROXY_MODE);
                    284:                        if (dynamic || (this->mode == MODE_TRANSPORT && !proxy_mode &&
                    285:                                                        !supplied))
                    286:                        {
                    287:                                e2 = hosts->create_enumerator(hosts);
                    288:                                while (e2->enumerate(e2, &host))
                    289:                                {
                    290:                                        ts2 = ts1->clone(ts1);
                    291:                                        if (dynamic || !host->is_anyaddr(host))
                    292:                                        {       /* don't make regular TS larger than they were */
                    293:                                                ts2->set_address(ts2, host);
                    294:                                        }
                    295:                                        derived->insert_last(derived, ts2);
                    296:                                }
                    297:                                e2->destroy(e2);
                    298:                                continue;
                    299:                        }
                    300:                }
                    301:                derived->insert_last(derived, ts1->clone(ts1));
                    302:        }
                    303:        e1->destroy(e1);
                    304: 
                    305:        if (log)
                    306:        {
                    307:                DBG2(DBG_CFG, "%s traffic selectors for %s:",
                    308:                         supplied ? "selecting" : "proposing", local ? "us" : "other");
                    309:        }
                    310:        if (!supplied)
                    311:        {
                    312:                while (derived->remove_first(derived, (void**)&ts1) == SUCCESS)
                    313:                {
                    314:                        if (log)
                    315:                        {
                    316:                                DBG2(DBG_CFG, " %R", ts1);
                    317:                        }
                    318:                        result->insert_last(result, ts1);
                    319:                }
                    320:                derived->destroy(derived);
                    321:        }
                    322:        else
                    323:        {
                    324:                e1 = derived->create_enumerator(derived);
                    325:                e2 = supplied->create_enumerator(supplied);
                    326:                /* enumerate all configured/derived selectors */
                    327:                while (e1->enumerate(e1, &ts1))
                    328:                {
                    329:                        /* enumerate all supplied traffic selectors */
                    330:                        while (e2->enumerate(e2, &ts2))
                    331:                        {
                    332:                                selected = ts1->get_subset(ts1, ts2);
                    333:                                if (selected)
                    334:                                {
                    335:                                        if (log)
                    336:                                        {
                    337:                                                DBG2(DBG_CFG, " config: %R, received: %R => match: %R",
                    338:                                                         ts1, ts2, selected);
                    339:                                        }
                    340:                                        result->insert_last(result, selected);
                    341:                                }
                    342:                                else if (log)
                    343:                                {
                    344:                                        DBG2(DBG_CFG, " config: %R, received: %R => no match",
                    345:                                                 ts1, ts2);
                    346:                                }
                    347:                        }
                    348:                        supplied->reset_enumerator(supplied, e2);
                    349:                }
                    350:                e1->destroy(e1);
                    351:                e2->destroy(e2);
                    352: 
                    353:                /* check if we/peer did any narrowing, raise alert */
                    354:                e1 = derived->create_enumerator(derived);
                    355:                e2 = result->create_enumerator(result);
                    356:                while (e1->enumerate(e1, &ts1))
                    357:                {
                    358:                        if (!e2->enumerate(e2, &ts2) || !ts1->equals(ts1, ts2))
                    359:                        {
                    360:                                charon->bus->alert(charon->bus, ALERT_TS_NARROWED,
                    361:                                                                   local, result, this);
                    362:                                break;
                    363:                        }
                    364:                }
                    365:                e1->destroy(e1);
                    366:                e2->destroy(e2);
                    367: 
                    368:                derived->destroy_offset(derived, offsetof(traffic_selector_t, destroy));
                    369:        }
                    370: 
                    371:        /* remove any redundant traffic selectors in the list */
                    372:        e1 = result->create_enumerator(result);
                    373:        e2 = result->create_enumerator(result);
                    374:        while (e1->enumerate(e1, &ts1))
                    375:        {
                    376:                while (e2->enumerate(e2, &ts2))
                    377:                {
                    378:                        if (ts1 != ts2)
                    379:                        {
                    380:                                if (ts2->is_contained_in(ts2, ts1))
                    381:                                {
                    382:                                        result->remove_at(result, e2);
                    383:                                        ts2->destroy(ts2);
                    384:                                        result->reset_enumerator(result, e1);
                    385:                                        break;
                    386:                                }
                    387:                                if (ts1->is_contained_in(ts1, ts2))
                    388:                                {
                    389:                                        result->remove_at(result, e1);
                    390:                                        ts1->destroy(ts1);
                    391:                                        break;
                    392:                                }
                    393:                        }
                    394:                }
                    395:                result->reset_enumerator(result, e2);
                    396:        }
                    397:        e1->destroy(e1);
                    398:        e2->destroy(e2);
                    399: 
                    400:        return result;
                    401: }
                    402: 
                    403: METHOD(child_cfg_t, get_updown, char*,
                    404:        private_child_cfg_t *this)
                    405: {
                    406:        return this->updown;
                    407: }
                    408: 
                    409: /**
                    410:  * Applies jitter to the rekey value. Returns the new rekey value.
                    411:  * Note: The distribution of random values is not perfect, but it
                    412:  * should get the job done.
                    413:  */
                    414: static uint64_t apply_jitter(uint64_t rekey, uint64_t jitter)
                    415: {
                    416:        if (jitter == 0)
                    417:        {
                    418:                return rekey;
                    419:        }
                    420:        jitter = (jitter == UINT64_MAX) ? jitter : jitter + 1;
                    421:        return rekey - jitter * (random() / (RAND_MAX + 1.0));
                    422: }
                    423: #define APPLY_JITTER(l) l.rekey = apply_jitter(l.rekey, l.jitter)
                    424: 
                    425: METHOD(child_cfg_t, get_lifetime, lifetime_cfg_t*,
                    426:        private_child_cfg_t *this, bool jitter)
                    427: {
                    428:        lifetime_cfg_t *lft = malloc_thing(lifetime_cfg_t);
                    429:        memcpy(lft, &this->lifetime, sizeof(lifetime_cfg_t));
                    430:        if (!jitter)
                    431:        {
                    432:                lft->time.jitter = lft->bytes.jitter = lft->packets.jitter = 0;
                    433:        }
                    434:        APPLY_JITTER(lft->time);
                    435:        APPLY_JITTER(lft->bytes);
                    436:        APPLY_JITTER(lft->packets);
                    437:        return lft;
                    438: }
                    439: 
                    440: METHOD(child_cfg_t, get_mode, ipsec_mode_t,
                    441:        private_child_cfg_t *this)
                    442: {
                    443:        return this->mode;
                    444: }
                    445: 
                    446: METHOD(child_cfg_t, get_start_action, action_t,
                    447:        private_child_cfg_t *this)
                    448: {
                    449:        return this->start_action;
                    450: }
                    451: 
                    452: METHOD(child_cfg_t, get_hw_offload, hw_offload_t,
                    453:        private_child_cfg_t *this)
                    454: {
                    455:        return this->hw_offload;
                    456: }
                    457: 
                    458: METHOD(child_cfg_t, get_copy_dscp, dscp_copy_t,
                    459:        private_child_cfg_t *this)
                    460: {
                    461:        return this->copy_dscp;
                    462: }
                    463: 
                    464: METHOD(child_cfg_t, get_dpd_action, action_t,
                    465:        private_child_cfg_t *this)
                    466: {
                    467:        return this->dpd_action;
                    468: }
                    469: 
                    470: METHOD(child_cfg_t, get_close_action, action_t,
                    471:        private_child_cfg_t *this)
                    472: {
                    473:        return this->close_action;
                    474: }
                    475: 
                    476: METHOD(child_cfg_t, get_dh_group, diffie_hellman_group_t,
                    477:        private_child_cfg_t *this)
                    478: {
                    479:        enumerator_t *enumerator;
                    480:        proposal_t *proposal;
                    481:        uint16_t dh_group = MODP_NONE;
                    482: 
                    483:        enumerator = this->proposals->create_enumerator(this->proposals);
                    484:        while (enumerator->enumerate(enumerator, &proposal))
                    485:        {
                    486:                if (proposal->get_algorithm(proposal, DIFFIE_HELLMAN_GROUP, &dh_group, NULL))
                    487:                {
                    488:                        break;
                    489:                }
                    490:        }
                    491:        enumerator->destroy(enumerator);
                    492:        return dh_group;
                    493: }
                    494: 
                    495: METHOD(child_cfg_t, get_inactivity, uint32_t,
                    496:        private_child_cfg_t *this)
                    497: {
                    498:        return this->inactivity;
                    499: }
                    500: 
                    501: METHOD(child_cfg_t, get_reqid, uint32_t,
                    502:        private_child_cfg_t *this)
                    503: {
                    504:        return this->reqid;
                    505: }
                    506: 
                    507: METHOD(child_cfg_t, get_if_id, uint32_t,
                    508:        private_child_cfg_t *this, bool inbound)
                    509: {
                    510:        return inbound ? this->if_id_in : this->if_id_out;
                    511: }
                    512: 
                    513: METHOD(child_cfg_t, get_mark, mark_t,
                    514:        private_child_cfg_t *this, bool inbound)
                    515: {
                    516:        return inbound ? this->mark_in : this->mark_out;
                    517: }
                    518: 
                    519: METHOD(child_cfg_t, get_set_mark, mark_t,
                    520:        private_child_cfg_t *this, bool inbound)
                    521: {
                    522:        return inbound ? this->set_mark_in : this->set_mark_out;
                    523: }
                    524: 
                    525: METHOD(child_cfg_t, get_tfc, uint32_t,
                    526:        private_child_cfg_t *this)
                    527: {
                    528:        return this->tfc;
                    529: }
                    530: 
                    531: METHOD(child_cfg_t, get_manual_prio, uint32_t,
                    532:        private_child_cfg_t *this)
                    533: {
                    534:        return this->manual_prio;
                    535: }
                    536: 
                    537: METHOD(child_cfg_t, get_interface, char*,
                    538:        private_child_cfg_t *this)
                    539: {
                    540:        return this->interface;
                    541: }
                    542: 
                    543: METHOD(child_cfg_t, get_replay_window, uint32_t,
                    544:        private_child_cfg_t *this)
                    545: {
                    546:        return this->replay_window;
                    547: }
                    548: 
                    549: METHOD(child_cfg_t, set_replay_window, void,
                    550:        private_child_cfg_t *this, uint32_t replay_window)
                    551: {
                    552:        this->replay_window = replay_window;
                    553: }
                    554: 
                    555: #define LT_PART_EQUALS(a, b) ({ a.life == b.life && a.rekey == b.rekey && a.jitter == b.jitter; })
                    556: #define LIFETIME_EQUALS(a, b) ({ LT_PART_EQUALS(a.time, b.time) && LT_PART_EQUALS(a.bytes, b.bytes) && LT_PART_EQUALS(a.packets, b.packets); })
                    557: 
                    558: METHOD(child_cfg_t, equals, bool,
                    559:        private_child_cfg_t *this, child_cfg_t *other_pub)
                    560: {
                    561:        private_child_cfg_t *other = (private_child_cfg_t*)other_pub;
                    562: 
                    563:        if (this == other)
                    564:        {
                    565:                return TRUE;
                    566:        }
                    567:        if (this->public.equals != other->public.equals)
                    568:        {
                    569:                return FALSE;
                    570:        }
                    571:        if (!this->proposals->equals_offset(this->proposals, other->proposals,
                    572:                                                                                offsetof(proposal_t, equals)))
                    573:        {
                    574:                return FALSE;
                    575:        }
                    576:        if (!this->my_ts->equals_offset(this->my_ts, other->my_ts,
                    577:                                                                        offsetof(traffic_selector_t, equals)))
                    578:        {
                    579:                return FALSE;
                    580:        }
                    581:        if (!this->other_ts->equals_offset(this->other_ts, other->other_ts,
                    582:                                                                           offsetof(traffic_selector_t, equals)))
                    583:        {
                    584:                return FALSE;
                    585:        }
                    586:        return this->options == other->options &&
                    587:                this->mode == other->mode &&
                    588:                this->start_action == other->start_action &&
                    589:                this->dpd_action == other->dpd_action &&
                    590:                this->close_action == other->close_action &&
                    591:                LIFETIME_EQUALS(this->lifetime, other->lifetime) &&
                    592:                this->inactivity == other->inactivity &&
                    593:                this->reqid == other->reqid &&
                    594:                this->if_id_in == other->if_id_in &&
                    595:                this->if_id_out == other->if_id_out &&
                    596:                this->mark_in.value == other->mark_in.value &&
                    597:                this->mark_in.mask == other->mark_in.mask &&
                    598:                this->mark_out.value == other->mark_out.value &&
                    599:                this->mark_out.mask == other->mark_out.mask &&
                    600:                this->set_mark_in.value == other->set_mark_in.value &&
                    601:                this->set_mark_in.mask == other->set_mark_in.mask &&
                    602:                this->set_mark_out.value == other->set_mark_out.value &&
                    603:                this->set_mark_out.mask == other->set_mark_out.mask &&
                    604:                this->tfc == other->tfc &&
                    605:                this->manual_prio == other->manual_prio &&
                    606:                this->replay_window == other->replay_window &&
                    607:                this->hw_offload == other->hw_offload &&
                    608:                this->copy_dscp == other->copy_dscp &&
                    609:                streq(this->updown, other->updown) &&
                    610:                streq(this->interface, other->interface);
                    611: }
                    612: 
                    613: METHOD(child_cfg_t, get_ref, child_cfg_t*,
                    614:        private_child_cfg_t *this)
                    615: {
                    616:        ref_get(&this->refcount);
                    617:        return &this->public;
                    618: }
                    619: 
                    620: METHOD(child_cfg_t, destroy, void,
                    621:        private_child_cfg_t *this)
                    622: {
                    623:        if (ref_put(&this->refcount))
                    624:        {
                    625:                this->proposals->destroy_offset(this->proposals, offsetof(proposal_t, destroy));
                    626:                this->my_ts->destroy_offset(this->my_ts, offsetof(traffic_selector_t, destroy));
                    627:                this->other_ts->destroy_offset(this->other_ts, offsetof(traffic_selector_t, destroy));
                    628:                free(this->updown);
                    629:                free(this->interface);
                    630:                free(this->name);
                    631:                free(this);
                    632:        }
                    633: }
                    634: 
                    635: /*
                    636:  * Described in header-file
                    637:  */
                    638: child_cfg_t *child_cfg_create(char *name, child_cfg_create_t *data)
                    639: {
                    640:        private_child_cfg_t *this;
                    641: 
                    642:        INIT(this,
                    643:                .public = {
                    644:                        .get_name = _get_name,
                    645:                        .add_traffic_selector = _add_traffic_selector,
                    646:                        .get_traffic_selectors = _get_traffic_selectors,
                    647:                        .add_proposal = _add_proposal,
                    648:                        .get_proposals = _get_proposals,
                    649:                        .select_proposal = _select_proposal,
                    650:                        .get_updown = _get_updown,
                    651:                        .get_mode = _get_mode,
                    652:                        .get_start_action = _get_start_action,
                    653:                        .get_dpd_action = _get_dpd_action,
                    654:                        .get_close_action = _get_close_action,
                    655:                        .get_lifetime = _get_lifetime,
                    656:                        .get_dh_group = _get_dh_group,
                    657:                        .get_inactivity = _get_inactivity,
                    658:                        .get_reqid = _get_reqid,
                    659:                        .get_if_id = _get_if_id,
                    660:                        .get_mark = _get_mark,
                    661:                        .get_set_mark = _get_set_mark,
                    662:                        .get_tfc = _get_tfc,
                    663:                        .get_manual_prio = _get_manual_prio,
                    664:                        .get_interface = _get_interface,
                    665:                        .get_replay_window = _get_replay_window,
                    666:                        .set_replay_window = _set_replay_window,
                    667:                        .has_option = _has_option,
                    668:                        .equals = _equals,
                    669:                        .get_ref = _get_ref,
                    670:                        .destroy = _destroy,
                    671:                        .get_hw_offload = _get_hw_offload,
                    672:                        .get_copy_dscp = _get_copy_dscp,
                    673:                },
                    674:                .name = strdup(name),
                    675:                .options = data->options,
                    676:                .updown = strdupnull(data->updown),
                    677:                .reqid = data->reqid,
                    678:                .if_id_in = data->if_id_in,
                    679:                .if_id_out = data->if_id_out,
                    680:                .mode = data->mode,
                    681:                .start_action = data->start_action,
                    682:                .dpd_action = data->dpd_action,
                    683:                .close_action = data->close_action,
                    684:                .mark_in = data->mark_in,
                    685:                .mark_out = data->mark_out,
                    686:                .set_mark_in = data->set_mark_in,
                    687:                .set_mark_out = data->set_mark_out,
                    688:                .lifetime = data->lifetime,
                    689:                .inactivity = data->inactivity,
                    690:                .tfc = data->tfc,
                    691:                .manual_prio = data->priority,
                    692:                .interface = strdupnull(data->interface),
                    693:                .refcount = 1,
                    694:                .proposals = linked_list_create(),
                    695:                .my_ts = linked_list_create(),
                    696:                .other_ts = linked_list_create(),
                    697:                .replay_window = lib->settings->get_int(lib->settings,
                    698:                                                        "%s.replay_window", DEFAULT_REPLAY_WINDOW, lib->ns),
                    699:                .hw_offload = data->hw_offload,
                    700:                .copy_dscp = data->copy_dscp,
                    701:        );
                    702: 
                    703:        return &this->public;
                    704: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>